1*4882a593Smuzhiyun // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2*4882a593Smuzhiyun /*******************************************************************************
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Module Name: dbtest - Various debug-related tests
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun ******************************************************************************/
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #include <acpi/acpi.h>
9*4882a593Smuzhiyun #include "accommon.h"
10*4882a593Smuzhiyun #include "acdebug.h"
11*4882a593Smuzhiyun #include "acnamesp.h"
12*4882a593Smuzhiyun #include "acpredef.h"
13*4882a593Smuzhiyun #include "acinterp.h"
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun #define _COMPONENT ACPI_CA_DEBUGGER
16*4882a593Smuzhiyun ACPI_MODULE_NAME("dbtest")
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun /* Local prototypes */
19*4882a593Smuzhiyun static void acpi_db_test_all_objects(void);
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun static acpi_status
22*4882a593Smuzhiyun acpi_db_test_one_object(acpi_handle obj_handle,
23*4882a593Smuzhiyun u32 nesting_level, void *context, void **return_value);
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun static acpi_status
26*4882a593Smuzhiyun acpi_db_test_integer_type(struct acpi_namespace_node *node, u32 bit_length);
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun static acpi_status
29*4882a593Smuzhiyun acpi_db_test_buffer_type(struct acpi_namespace_node *node, u32 bit_length);
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun static acpi_status
32*4882a593Smuzhiyun acpi_db_test_string_type(struct acpi_namespace_node *node, u32 byte_length);
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun static acpi_status acpi_db_test_package_type(struct acpi_namespace_node *node);
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun static acpi_status
37*4882a593Smuzhiyun acpi_db_test_field_unit_type(union acpi_operand_object *obj_desc);
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun static acpi_status
40*4882a593Smuzhiyun acpi_db_read_from_object(struct acpi_namespace_node *node,
41*4882a593Smuzhiyun acpi_object_type expected_type,
42*4882a593Smuzhiyun union acpi_object **value);
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun static acpi_status
45*4882a593Smuzhiyun acpi_db_write_to_object(struct acpi_namespace_node *node,
46*4882a593Smuzhiyun union acpi_object *value);
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun static void acpi_db_evaluate_all_predefined_names(char *count_arg);
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun static acpi_status
51*4882a593Smuzhiyun acpi_db_evaluate_one_predefined_name(acpi_handle obj_handle,
52*4882a593Smuzhiyun u32 nesting_level,
53*4882a593Smuzhiyun void *context, void **return_value);
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun /*
56*4882a593Smuzhiyun * Test subcommands
57*4882a593Smuzhiyun */
58*4882a593Smuzhiyun static struct acpi_db_argument_info acpi_db_test_types[] = {
59*4882a593Smuzhiyun {"OBJECTS"},
60*4882a593Smuzhiyun {"PREDEFINED"},
61*4882a593Smuzhiyun {NULL} /* Must be null terminated */
62*4882a593Smuzhiyun };
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun #define CMD_TEST_OBJECTS 0
65*4882a593Smuzhiyun #define CMD_TEST_PREDEFINED 1
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun #define BUFFER_FILL_VALUE 0xFF
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun /*
70*4882a593Smuzhiyun * Support for the special debugger read/write control methods.
71*4882a593Smuzhiyun * These methods are installed into the current namespace and are
72*4882a593Smuzhiyun * used to read and write the various namespace objects. The point
73*4882a593Smuzhiyun * is to force the AML interpreter do all of the work.
74*4882a593Smuzhiyun */
75*4882a593Smuzhiyun #define ACPI_DB_READ_METHOD "\\_T98"
76*4882a593Smuzhiyun #define ACPI_DB_WRITE_METHOD "\\_T99"
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun static acpi_handle read_handle = NULL;
79*4882a593Smuzhiyun static acpi_handle write_handle = NULL;
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun /* ASL Definitions of the debugger read/write control methods. AML below. */
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun #if 0
84*4882a593Smuzhiyun definition_block("ssdt.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
85*4882a593Smuzhiyun {
86*4882a593Smuzhiyun method(_T98, 1, not_serialized) { /* Read */
87*4882a593Smuzhiyun return (de_ref_of(arg0))
88*4882a593Smuzhiyun }
89*4882a593Smuzhiyun }
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun definition_block("ssdt2.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
92*4882a593Smuzhiyun {
93*4882a593Smuzhiyun method(_T99, 2, not_serialized) { /* Write */
94*4882a593Smuzhiyun store(arg1, arg0)
95*4882a593Smuzhiyun }
96*4882a593Smuzhiyun }
97*4882a593Smuzhiyun #endif
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun static unsigned char read_method_code[] = {
100*4882a593Smuzhiyun 0x53, 0x53, 0x44, 0x54, 0x2E, 0x00, 0x00, 0x00, /* 00000000 "SSDT...." */
101*4882a593Smuzhiyun 0x02, 0xC9, 0x49, 0x6E, 0x74, 0x65, 0x6C, 0x00, /* 00000008 "..Intel." */
102*4882a593Smuzhiyun 0x44, 0x45, 0x42, 0x55, 0x47, 0x00, 0x00, 0x00, /* 00000010 "DEBUG..." */
103*4882a593Smuzhiyun 0x01, 0x00, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* 00000018 "....INTL" */
104*4882a593Smuzhiyun 0x18, 0x12, 0x13, 0x20, 0x14, 0x09, 0x5F, 0x54, /* 00000020 "... .._T" */
105*4882a593Smuzhiyun 0x39, 0x38, 0x01, 0xA4, 0x83, 0x68 /* 00000028 "98...h" */
106*4882a593Smuzhiyun };
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun static unsigned char write_method_code[] = {
109*4882a593Smuzhiyun 0x53, 0x53, 0x44, 0x54, 0x2E, 0x00, 0x00, 0x00, /* 00000000 "SSDT...." */
110*4882a593Smuzhiyun 0x02, 0x15, 0x49, 0x6E, 0x74, 0x65, 0x6C, 0x00, /* 00000008 "..Intel." */
111*4882a593Smuzhiyun 0x44, 0x45, 0x42, 0x55, 0x47, 0x00, 0x00, 0x00, /* 00000010 "DEBUG..." */
112*4882a593Smuzhiyun 0x01, 0x00, 0x00, 0x00, 0x49, 0x4E, 0x54, 0x4C, /* 00000018 "....INTL" */
113*4882a593Smuzhiyun 0x18, 0x12, 0x13, 0x20, 0x14, 0x09, 0x5F, 0x54, /* 00000020 "... .._T" */
114*4882a593Smuzhiyun 0x39, 0x39, 0x02, 0x70, 0x69, 0x68 /* 00000028 "99.pih" */
115*4882a593Smuzhiyun };
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun /*******************************************************************************
118*4882a593Smuzhiyun *
119*4882a593Smuzhiyun * FUNCTION: acpi_db_execute_test
120*4882a593Smuzhiyun *
121*4882a593Smuzhiyun * PARAMETERS: type_arg - Subcommand
122*4882a593Smuzhiyun *
123*4882a593Smuzhiyun * RETURN: None
124*4882a593Smuzhiyun *
125*4882a593Smuzhiyun * DESCRIPTION: Execute various debug tests.
126*4882a593Smuzhiyun *
127*4882a593Smuzhiyun * Note: Code is prepared for future expansion of the TEST command.
128*4882a593Smuzhiyun *
129*4882a593Smuzhiyun ******************************************************************************/
130*4882a593Smuzhiyun
acpi_db_execute_test(char * type_arg)131*4882a593Smuzhiyun void acpi_db_execute_test(char *type_arg)
132*4882a593Smuzhiyun {
133*4882a593Smuzhiyun u32 temp;
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun acpi_ut_strupr(type_arg);
136*4882a593Smuzhiyun temp = acpi_db_match_argument(type_arg, acpi_db_test_types);
137*4882a593Smuzhiyun if (temp == ACPI_TYPE_NOT_FOUND) {
138*4882a593Smuzhiyun acpi_os_printf("Invalid or unsupported argument\n");
139*4882a593Smuzhiyun return;
140*4882a593Smuzhiyun }
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun switch (temp) {
143*4882a593Smuzhiyun case CMD_TEST_OBJECTS:
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun acpi_db_test_all_objects();
146*4882a593Smuzhiyun break;
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun case CMD_TEST_PREDEFINED:
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun acpi_db_evaluate_all_predefined_names(NULL);
151*4882a593Smuzhiyun break;
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun default:
154*4882a593Smuzhiyun break;
155*4882a593Smuzhiyun }
156*4882a593Smuzhiyun }
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun /*******************************************************************************
159*4882a593Smuzhiyun *
160*4882a593Smuzhiyun * FUNCTION: acpi_db_test_all_objects
161*4882a593Smuzhiyun *
162*4882a593Smuzhiyun * PARAMETERS: None
163*4882a593Smuzhiyun *
164*4882a593Smuzhiyun * RETURN: None
165*4882a593Smuzhiyun *
166*4882a593Smuzhiyun * DESCRIPTION: This test implements the OBJECTS subcommand. It exercises the
167*4882a593Smuzhiyun * namespace by reading/writing/comparing all data objects such
168*4882a593Smuzhiyun * as integers, strings, buffers, fields, buffer fields, etc.
169*4882a593Smuzhiyun *
170*4882a593Smuzhiyun ******************************************************************************/
171*4882a593Smuzhiyun
acpi_db_test_all_objects(void)172*4882a593Smuzhiyun static void acpi_db_test_all_objects(void)
173*4882a593Smuzhiyun {
174*4882a593Smuzhiyun acpi_status status;
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun /* Install the debugger read-object control method if necessary */
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun if (!read_handle) {
179*4882a593Smuzhiyun status = acpi_install_method(read_method_code);
180*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
181*4882a593Smuzhiyun acpi_os_printf
182*4882a593Smuzhiyun ("%s, Could not install debugger read method\n",
183*4882a593Smuzhiyun acpi_format_exception(status));
184*4882a593Smuzhiyun return;
185*4882a593Smuzhiyun }
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun status =
188*4882a593Smuzhiyun acpi_get_handle(NULL, ACPI_DB_READ_METHOD, &read_handle);
189*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
190*4882a593Smuzhiyun acpi_os_printf
191*4882a593Smuzhiyun ("Could not obtain handle for debug method %s\n",
192*4882a593Smuzhiyun ACPI_DB_READ_METHOD);
193*4882a593Smuzhiyun return;
194*4882a593Smuzhiyun }
195*4882a593Smuzhiyun }
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun /* Install the debugger write-object control method if necessary */
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun if (!write_handle) {
200*4882a593Smuzhiyun status = acpi_install_method(write_method_code);
201*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
202*4882a593Smuzhiyun acpi_os_printf
203*4882a593Smuzhiyun ("%s, Could not install debugger write method\n",
204*4882a593Smuzhiyun acpi_format_exception(status));
205*4882a593Smuzhiyun return;
206*4882a593Smuzhiyun }
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun status =
209*4882a593Smuzhiyun acpi_get_handle(NULL, ACPI_DB_WRITE_METHOD, &write_handle);
210*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
211*4882a593Smuzhiyun acpi_os_printf
212*4882a593Smuzhiyun ("Could not obtain handle for debug method %s\n",
213*4882a593Smuzhiyun ACPI_DB_WRITE_METHOD);
214*4882a593Smuzhiyun return;
215*4882a593Smuzhiyun }
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun /* Walk the entire namespace, testing each supported named data object */
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
221*4882a593Smuzhiyun ACPI_UINT32_MAX, acpi_db_test_one_object,
222*4882a593Smuzhiyun NULL, NULL, NULL);
223*4882a593Smuzhiyun }
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun /*******************************************************************************
226*4882a593Smuzhiyun *
227*4882a593Smuzhiyun * FUNCTION: acpi_db_test_one_object
228*4882a593Smuzhiyun *
229*4882a593Smuzhiyun * PARAMETERS: acpi_walk_callback
230*4882a593Smuzhiyun *
231*4882a593Smuzhiyun * RETURN: Status
232*4882a593Smuzhiyun *
233*4882a593Smuzhiyun * DESCRIPTION: Test one namespace object. Supported types are Integer,
234*4882a593Smuzhiyun * String, Buffer, Package, buffer_field, and field_unit.
235*4882a593Smuzhiyun * All other object types are simply ignored.
236*4882a593Smuzhiyun *
237*4882a593Smuzhiyun ******************************************************************************/
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun static acpi_status
acpi_db_test_one_object(acpi_handle obj_handle,u32 nesting_level,void * context,void ** return_value)240*4882a593Smuzhiyun acpi_db_test_one_object(acpi_handle obj_handle,
241*4882a593Smuzhiyun u32 nesting_level, void *context, void **return_value)
242*4882a593Smuzhiyun {
243*4882a593Smuzhiyun struct acpi_namespace_node *node;
244*4882a593Smuzhiyun union acpi_operand_object *obj_desc;
245*4882a593Smuzhiyun acpi_object_type local_type;
246*4882a593Smuzhiyun u32 bit_length = 0;
247*4882a593Smuzhiyun u32 byte_length = 0;
248*4882a593Smuzhiyun acpi_status status = AE_OK;
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
251*4882a593Smuzhiyun obj_desc = node->object;
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun /*
254*4882a593Smuzhiyun * For the supported types, get the actual bit length or
255*4882a593Smuzhiyun * byte length. Map the type to one of Integer/String/Buffer.
256*4882a593Smuzhiyun */
257*4882a593Smuzhiyun switch (node->type) {
258*4882a593Smuzhiyun case ACPI_TYPE_INTEGER:
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun /* Integer width is either 32 or 64 */
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun local_type = ACPI_TYPE_INTEGER;
263*4882a593Smuzhiyun bit_length = acpi_gbl_integer_bit_width;
264*4882a593Smuzhiyun break;
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun case ACPI_TYPE_STRING:
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun local_type = ACPI_TYPE_STRING;
269*4882a593Smuzhiyun byte_length = obj_desc->string.length;
270*4882a593Smuzhiyun break;
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun case ACPI_TYPE_BUFFER:
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun local_type = ACPI_TYPE_BUFFER;
275*4882a593Smuzhiyun byte_length = obj_desc->buffer.length;
276*4882a593Smuzhiyun bit_length = byte_length * 8;
277*4882a593Smuzhiyun break;
278*4882a593Smuzhiyun
279*4882a593Smuzhiyun case ACPI_TYPE_PACKAGE:
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun local_type = ACPI_TYPE_PACKAGE;
282*4882a593Smuzhiyun break;
283*4882a593Smuzhiyun
284*4882a593Smuzhiyun case ACPI_TYPE_FIELD_UNIT:
285*4882a593Smuzhiyun case ACPI_TYPE_LOCAL_REGION_FIELD:
286*4882a593Smuzhiyun case ACPI_TYPE_LOCAL_INDEX_FIELD:
287*4882a593Smuzhiyun case ACPI_TYPE_LOCAL_BANK_FIELD:
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun local_type = ACPI_TYPE_FIELD_UNIT;
290*4882a593Smuzhiyun break;
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun case ACPI_TYPE_BUFFER_FIELD:
293*4882a593Smuzhiyun /*
294*4882a593Smuzhiyun * The returned object will be a Buffer if the field length
295*4882a593Smuzhiyun * is larger than the size of an Integer (32 or 64 bits
296*4882a593Smuzhiyun * depending on the DSDT version).
297*4882a593Smuzhiyun */
298*4882a593Smuzhiyun local_type = ACPI_TYPE_INTEGER;
299*4882a593Smuzhiyun if (obj_desc) {
300*4882a593Smuzhiyun bit_length = obj_desc->common_field.bit_length;
301*4882a593Smuzhiyun byte_length = ACPI_ROUND_BITS_UP_TO_BYTES(bit_length);
302*4882a593Smuzhiyun if (bit_length > acpi_gbl_integer_bit_width) {
303*4882a593Smuzhiyun local_type = ACPI_TYPE_BUFFER;
304*4882a593Smuzhiyun }
305*4882a593Smuzhiyun }
306*4882a593Smuzhiyun break;
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun default:
309*4882a593Smuzhiyun
310*4882a593Smuzhiyun /* Ignore all non-data types - Methods, Devices, Scopes, etc. */
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun return (AE_OK);
313*4882a593Smuzhiyun }
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun /* Emit the common prefix: Type:Name */
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun acpi_os_printf("%14s: %4.4s",
318*4882a593Smuzhiyun acpi_ut_get_type_name(node->type), node->name.ascii);
319*4882a593Smuzhiyun
320*4882a593Smuzhiyun if (!obj_desc) {
321*4882a593Smuzhiyun acpi_os_printf(" No attached sub-object, ignoring\n");
322*4882a593Smuzhiyun return (AE_OK);
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun /* At this point, we have resolved the object to one of the major types */
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun switch (local_type) {
328*4882a593Smuzhiyun case ACPI_TYPE_INTEGER:
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun status = acpi_db_test_integer_type(node, bit_length);
331*4882a593Smuzhiyun break;
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun case ACPI_TYPE_STRING:
334*4882a593Smuzhiyun
335*4882a593Smuzhiyun status = acpi_db_test_string_type(node, byte_length);
336*4882a593Smuzhiyun break;
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun case ACPI_TYPE_BUFFER:
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun status = acpi_db_test_buffer_type(node, bit_length);
341*4882a593Smuzhiyun break;
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun case ACPI_TYPE_PACKAGE:
344*4882a593Smuzhiyun
345*4882a593Smuzhiyun status = acpi_db_test_package_type(node);
346*4882a593Smuzhiyun break;
347*4882a593Smuzhiyun
348*4882a593Smuzhiyun case ACPI_TYPE_FIELD_UNIT:
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun status = acpi_db_test_field_unit_type(obj_desc);
351*4882a593Smuzhiyun break;
352*4882a593Smuzhiyun
353*4882a593Smuzhiyun default:
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun acpi_os_printf(" Ignoring, type not implemented (%2.2X)",
356*4882a593Smuzhiyun local_type);
357*4882a593Smuzhiyun break;
358*4882a593Smuzhiyun }
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun /* Exit on error, but don't abort the namespace walk */
361*4882a593Smuzhiyun
362*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
363*4882a593Smuzhiyun status = AE_OK;
364*4882a593Smuzhiyun }
365*4882a593Smuzhiyun
366*4882a593Smuzhiyun acpi_os_printf("\n");
367*4882a593Smuzhiyun return (status);
368*4882a593Smuzhiyun }
369*4882a593Smuzhiyun
370*4882a593Smuzhiyun /*******************************************************************************
371*4882a593Smuzhiyun *
372*4882a593Smuzhiyun * FUNCTION: acpi_db_test_integer_type
373*4882a593Smuzhiyun *
374*4882a593Smuzhiyun * PARAMETERS: node - Parent NS node for the object
375*4882a593Smuzhiyun * bit_length - Actual length of the object. Used for
376*4882a593Smuzhiyun * support of arbitrary length field_unit
377*4882a593Smuzhiyun * and buffer_field objects.
378*4882a593Smuzhiyun *
379*4882a593Smuzhiyun * RETURN: Status
380*4882a593Smuzhiyun *
381*4882a593Smuzhiyun * DESCRIPTION: Test read/write for an Integer-valued object. Performs a
382*4882a593Smuzhiyun * write/read/compare of an arbitrary new value, then performs
383*4882a593Smuzhiyun * a write/read/compare of the original value.
384*4882a593Smuzhiyun *
385*4882a593Smuzhiyun ******************************************************************************/
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun static acpi_status
acpi_db_test_integer_type(struct acpi_namespace_node * node,u32 bit_length)388*4882a593Smuzhiyun acpi_db_test_integer_type(struct acpi_namespace_node *node, u32 bit_length)
389*4882a593Smuzhiyun {
390*4882a593Smuzhiyun union acpi_object *temp1 = NULL;
391*4882a593Smuzhiyun union acpi_object *temp2 = NULL;
392*4882a593Smuzhiyun union acpi_object *temp3 = NULL;
393*4882a593Smuzhiyun union acpi_object write_value;
394*4882a593Smuzhiyun u64 value_to_write;
395*4882a593Smuzhiyun acpi_status status;
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun if (bit_length > 64) {
398*4882a593Smuzhiyun acpi_os_printf(" Invalid length for an Integer: %u",
399*4882a593Smuzhiyun bit_length);
400*4882a593Smuzhiyun return (AE_OK);
401*4882a593Smuzhiyun }
402*4882a593Smuzhiyun
403*4882a593Smuzhiyun /* Read the original value */
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp1);
406*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
407*4882a593Smuzhiyun return (status);
408*4882a593Smuzhiyun }
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun acpi_os_printf(ACPI_DEBUG_LENGTH_FORMAT " %8.8X%8.8X",
411*4882a593Smuzhiyun bit_length, ACPI_ROUND_BITS_UP_TO_BYTES(bit_length),
412*4882a593Smuzhiyun ACPI_FORMAT_UINT64(temp1->integer.value));
413*4882a593Smuzhiyun
414*4882a593Smuzhiyun value_to_write = ACPI_UINT64_MAX >> (64 - bit_length);
415*4882a593Smuzhiyun if (temp1->integer.value == value_to_write) {
416*4882a593Smuzhiyun value_to_write = 0;
417*4882a593Smuzhiyun }
418*4882a593Smuzhiyun /* Write a new value */
419*4882a593Smuzhiyun
420*4882a593Smuzhiyun write_value.type = ACPI_TYPE_INTEGER;
421*4882a593Smuzhiyun write_value.integer.value = value_to_write;
422*4882a593Smuzhiyun status = acpi_db_write_to_object(node, &write_value);
423*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
424*4882a593Smuzhiyun goto exit;
425*4882a593Smuzhiyun }
426*4882a593Smuzhiyun
427*4882a593Smuzhiyun /* Ensure that we can read back the new value */
428*4882a593Smuzhiyun
429*4882a593Smuzhiyun status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp2);
430*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
431*4882a593Smuzhiyun goto exit;
432*4882a593Smuzhiyun }
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun if (temp2->integer.value != value_to_write) {
435*4882a593Smuzhiyun acpi_os_printf(" MISMATCH 2: %8.8X%8.8X, expecting %8.8X%8.8X",
436*4882a593Smuzhiyun ACPI_FORMAT_UINT64(temp2->integer.value),
437*4882a593Smuzhiyun ACPI_FORMAT_UINT64(value_to_write));
438*4882a593Smuzhiyun }
439*4882a593Smuzhiyun
440*4882a593Smuzhiyun /* Write back the original value */
441*4882a593Smuzhiyun
442*4882a593Smuzhiyun write_value.integer.value = temp1->integer.value;
443*4882a593Smuzhiyun status = acpi_db_write_to_object(node, &write_value);
444*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
445*4882a593Smuzhiyun goto exit;
446*4882a593Smuzhiyun }
447*4882a593Smuzhiyun
448*4882a593Smuzhiyun /* Ensure that we can read back the original value */
449*4882a593Smuzhiyun
450*4882a593Smuzhiyun status = acpi_db_read_from_object(node, ACPI_TYPE_INTEGER, &temp3);
451*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
452*4882a593Smuzhiyun goto exit;
453*4882a593Smuzhiyun }
454*4882a593Smuzhiyun
455*4882a593Smuzhiyun if (temp3->integer.value != temp1->integer.value) {
456*4882a593Smuzhiyun acpi_os_printf(" MISMATCH 3: %8.8X%8.8X, expecting %8.8X%8.8X",
457*4882a593Smuzhiyun ACPI_FORMAT_UINT64(temp3->integer.value),
458*4882a593Smuzhiyun ACPI_FORMAT_UINT64(temp1->integer.value));
459*4882a593Smuzhiyun }
460*4882a593Smuzhiyun
461*4882a593Smuzhiyun exit:
462*4882a593Smuzhiyun if (temp1) {
463*4882a593Smuzhiyun acpi_os_free(temp1);
464*4882a593Smuzhiyun }
465*4882a593Smuzhiyun if (temp2) {
466*4882a593Smuzhiyun acpi_os_free(temp2);
467*4882a593Smuzhiyun }
468*4882a593Smuzhiyun if (temp3) {
469*4882a593Smuzhiyun acpi_os_free(temp3);
470*4882a593Smuzhiyun }
471*4882a593Smuzhiyun return (AE_OK);
472*4882a593Smuzhiyun }
473*4882a593Smuzhiyun
474*4882a593Smuzhiyun /*******************************************************************************
475*4882a593Smuzhiyun *
476*4882a593Smuzhiyun * FUNCTION: acpi_db_test_buffer_type
477*4882a593Smuzhiyun *
478*4882a593Smuzhiyun * PARAMETERS: node - Parent NS node for the object
479*4882a593Smuzhiyun * bit_length - Actual length of the object.
480*4882a593Smuzhiyun *
481*4882a593Smuzhiyun * RETURN: Status
482*4882a593Smuzhiyun *
483*4882a593Smuzhiyun * DESCRIPTION: Test read/write for an Buffer-valued object. Performs a
484*4882a593Smuzhiyun * write/read/compare of an arbitrary new value, then performs
485*4882a593Smuzhiyun * a write/read/compare of the original value.
486*4882a593Smuzhiyun *
487*4882a593Smuzhiyun ******************************************************************************/
488*4882a593Smuzhiyun
489*4882a593Smuzhiyun static acpi_status
acpi_db_test_buffer_type(struct acpi_namespace_node * node,u32 bit_length)490*4882a593Smuzhiyun acpi_db_test_buffer_type(struct acpi_namespace_node *node, u32 bit_length)
491*4882a593Smuzhiyun {
492*4882a593Smuzhiyun union acpi_object *temp1 = NULL;
493*4882a593Smuzhiyun union acpi_object *temp2 = NULL;
494*4882a593Smuzhiyun union acpi_object *temp3 = NULL;
495*4882a593Smuzhiyun u8 *buffer;
496*4882a593Smuzhiyun union acpi_object write_value;
497*4882a593Smuzhiyun acpi_status status;
498*4882a593Smuzhiyun u32 byte_length;
499*4882a593Smuzhiyun u32 i;
500*4882a593Smuzhiyun u8 extra_bits;
501*4882a593Smuzhiyun
502*4882a593Smuzhiyun byte_length = ACPI_ROUND_BITS_UP_TO_BYTES(bit_length);
503*4882a593Smuzhiyun if (byte_length == 0) {
504*4882a593Smuzhiyun acpi_os_printf(" Ignoring zero length buffer");
505*4882a593Smuzhiyun return (AE_OK);
506*4882a593Smuzhiyun }
507*4882a593Smuzhiyun
508*4882a593Smuzhiyun /* Allocate a local buffer */
509*4882a593Smuzhiyun
510*4882a593Smuzhiyun buffer = ACPI_ALLOCATE_ZEROED(byte_length);
511*4882a593Smuzhiyun if (!buffer) {
512*4882a593Smuzhiyun return (AE_NO_MEMORY);
513*4882a593Smuzhiyun }
514*4882a593Smuzhiyun
515*4882a593Smuzhiyun /* Read the original value */
516*4882a593Smuzhiyun
517*4882a593Smuzhiyun status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp1);
518*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
519*4882a593Smuzhiyun goto exit;
520*4882a593Smuzhiyun }
521*4882a593Smuzhiyun
522*4882a593Smuzhiyun /* Emit a few bytes of the buffer */
523*4882a593Smuzhiyun
524*4882a593Smuzhiyun acpi_os_printf(ACPI_DEBUG_LENGTH_FORMAT, bit_length,
525*4882a593Smuzhiyun temp1->buffer.length);
526*4882a593Smuzhiyun for (i = 0; ((i < 8) && (i < byte_length)); i++) {
527*4882a593Smuzhiyun acpi_os_printf(" %2.2X", temp1->buffer.pointer[i]);
528*4882a593Smuzhiyun }
529*4882a593Smuzhiyun acpi_os_printf("... ");
530*4882a593Smuzhiyun
531*4882a593Smuzhiyun /*
532*4882a593Smuzhiyun * Write a new value.
533*4882a593Smuzhiyun *
534*4882a593Smuzhiyun * Handle possible extra bits at the end of the buffer. Can
535*4882a593Smuzhiyun * happen for field_units larger than an integer, but the bit
536*4882a593Smuzhiyun * count is not an integral number of bytes. Zero out the
537*4882a593Smuzhiyun * unused bits.
538*4882a593Smuzhiyun */
539*4882a593Smuzhiyun memset(buffer, BUFFER_FILL_VALUE, byte_length);
540*4882a593Smuzhiyun extra_bits = bit_length % 8;
541*4882a593Smuzhiyun if (extra_bits) {
542*4882a593Smuzhiyun buffer[byte_length - 1] = ACPI_MASK_BITS_ABOVE(extra_bits);
543*4882a593Smuzhiyun }
544*4882a593Smuzhiyun
545*4882a593Smuzhiyun write_value.type = ACPI_TYPE_BUFFER;
546*4882a593Smuzhiyun write_value.buffer.length = byte_length;
547*4882a593Smuzhiyun write_value.buffer.pointer = buffer;
548*4882a593Smuzhiyun
549*4882a593Smuzhiyun status = acpi_db_write_to_object(node, &write_value);
550*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
551*4882a593Smuzhiyun goto exit;
552*4882a593Smuzhiyun }
553*4882a593Smuzhiyun
554*4882a593Smuzhiyun /* Ensure that we can read back the new value */
555*4882a593Smuzhiyun
556*4882a593Smuzhiyun status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp2);
557*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
558*4882a593Smuzhiyun goto exit;
559*4882a593Smuzhiyun }
560*4882a593Smuzhiyun
561*4882a593Smuzhiyun if (memcmp(temp2->buffer.pointer, buffer, byte_length)) {
562*4882a593Smuzhiyun acpi_os_printf(" MISMATCH 2: New buffer value");
563*4882a593Smuzhiyun }
564*4882a593Smuzhiyun
565*4882a593Smuzhiyun /* Write back the original value */
566*4882a593Smuzhiyun
567*4882a593Smuzhiyun write_value.buffer.length = byte_length;
568*4882a593Smuzhiyun write_value.buffer.pointer = temp1->buffer.pointer;
569*4882a593Smuzhiyun
570*4882a593Smuzhiyun status = acpi_db_write_to_object(node, &write_value);
571*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
572*4882a593Smuzhiyun goto exit;
573*4882a593Smuzhiyun }
574*4882a593Smuzhiyun
575*4882a593Smuzhiyun /* Ensure that we can read back the original value */
576*4882a593Smuzhiyun
577*4882a593Smuzhiyun status = acpi_db_read_from_object(node, ACPI_TYPE_BUFFER, &temp3);
578*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
579*4882a593Smuzhiyun goto exit;
580*4882a593Smuzhiyun }
581*4882a593Smuzhiyun
582*4882a593Smuzhiyun if (memcmp(temp1->buffer.pointer, temp3->buffer.pointer, byte_length)) {
583*4882a593Smuzhiyun acpi_os_printf(" MISMATCH 3: While restoring original buffer");
584*4882a593Smuzhiyun }
585*4882a593Smuzhiyun
586*4882a593Smuzhiyun exit:
587*4882a593Smuzhiyun ACPI_FREE(buffer);
588*4882a593Smuzhiyun if (temp1) {
589*4882a593Smuzhiyun acpi_os_free(temp1);
590*4882a593Smuzhiyun }
591*4882a593Smuzhiyun if (temp2) {
592*4882a593Smuzhiyun acpi_os_free(temp2);
593*4882a593Smuzhiyun }
594*4882a593Smuzhiyun if (temp3) {
595*4882a593Smuzhiyun acpi_os_free(temp3);
596*4882a593Smuzhiyun }
597*4882a593Smuzhiyun return (status);
598*4882a593Smuzhiyun }
599*4882a593Smuzhiyun
600*4882a593Smuzhiyun /*******************************************************************************
601*4882a593Smuzhiyun *
602*4882a593Smuzhiyun * FUNCTION: acpi_db_test_string_type
603*4882a593Smuzhiyun *
604*4882a593Smuzhiyun * PARAMETERS: node - Parent NS node for the object
605*4882a593Smuzhiyun * byte_length - Actual length of the object.
606*4882a593Smuzhiyun *
607*4882a593Smuzhiyun * RETURN: Status
608*4882a593Smuzhiyun *
609*4882a593Smuzhiyun * DESCRIPTION: Test read/write for an String-valued object. Performs a
610*4882a593Smuzhiyun * write/read/compare of an arbitrary new value, then performs
611*4882a593Smuzhiyun * a write/read/compare of the original value.
612*4882a593Smuzhiyun *
613*4882a593Smuzhiyun ******************************************************************************/
614*4882a593Smuzhiyun
615*4882a593Smuzhiyun static acpi_status
acpi_db_test_string_type(struct acpi_namespace_node * node,u32 byte_length)616*4882a593Smuzhiyun acpi_db_test_string_type(struct acpi_namespace_node *node, u32 byte_length)
617*4882a593Smuzhiyun {
618*4882a593Smuzhiyun union acpi_object *temp1 = NULL;
619*4882a593Smuzhiyun union acpi_object *temp2 = NULL;
620*4882a593Smuzhiyun union acpi_object *temp3 = NULL;
621*4882a593Smuzhiyun char *value_to_write = "Test String from AML Debugger";
622*4882a593Smuzhiyun union acpi_object write_value;
623*4882a593Smuzhiyun acpi_status status;
624*4882a593Smuzhiyun
625*4882a593Smuzhiyun /* Read the original value */
626*4882a593Smuzhiyun
627*4882a593Smuzhiyun status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp1);
628*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
629*4882a593Smuzhiyun return (status);
630*4882a593Smuzhiyun }
631*4882a593Smuzhiyun
632*4882a593Smuzhiyun acpi_os_printf(ACPI_DEBUG_LENGTH_FORMAT " \"%s\"",
633*4882a593Smuzhiyun (temp1->string.length * 8), temp1->string.length,
634*4882a593Smuzhiyun temp1->string.pointer);
635*4882a593Smuzhiyun
636*4882a593Smuzhiyun /* Write a new value */
637*4882a593Smuzhiyun
638*4882a593Smuzhiyun write_value.type = ACPI_TYPE_STRING;
639*4882a593Smuzhiyun write_value.string.length = strlen(value_to_write);
640*4882a593Smuzhiyun write_value.string.pointer = value_to_write;
641*4882a593Smuzhiyun
642*4882a593Smuzhiyun status = acpi_db_write_to_object(node, &write_value);
643*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
644*4882a593Smuzhiyun goto exit;
645*4882a593Smuzhiyun }
646*4882a593Smuzhiyun
647*4882a593Smuzhiyun /* Ensure that we can read back the new value */
648*4882a593Smuzhiyun
649*4882a593Smuzhiyun status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp2);
650*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
651*4882a593Smuzhiyun goto exit;
652*4882a593Smuzhiyun }
653*4882a593Smuzhiyun
654*4882a593Smuzhiyun if (strcmp(temp2->string.pointer, value_to_write)) {
655*4882a593Smuzhiyun acpi_os_printf(" MISMATCH 2: %s, expecting %s",
656*4882a593Smuzhiyun temp2->string.pointer, value_to_write);
657*4882a593Smuzhiyun }
658*4882a593Smuzhiyun
659*4882a593Smuzhiyun /* Write back the original value */
660*4882a593Smuzhiyun
661*4882a593Smuzhiyun write_value.string.length = strlen(temp1->string.pointer);
662*4882a593Smuzhiyun write_value.string.pointer = temp1->string.pointer;
663*4882a593Smuzhiyun
664*4882a593Smuzhiyun status = acpi_db_write_to_object(node, &write_value);
665*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
666*4882a593Smuzhiyun goto exit;
667*4882a593Smuzhiyun }
668*4882a593Smuzhiyun
669*4882a593Smuzhiyun /* Ensure that we can read back the original value */
670*4882a593Smuzhiyun
671*4882a593Smuzhiyun status = acpi_db_read_from_object(node, ACPI_TYPE_STRING, &temp3);
672*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
673*4882a593Smuzhiyun goto exit;
674*4882a593Smuzhiyun }
675*4882a593Smuzhiyun
676*4882a593Smuzhiyun if (strcmp(temp1->string.pointer, temp3->string.pointer)) {
677*4882a593Smuzhiyun acpi_os_printf(" MISMATCH 3: %s, expecting %s",
678*4882a593Smuzhiyun temp3->string.pointer, temp1->string.pointer);
679*4882a593Smuzhiyun }
680*4882a593Smuzhiyun
681*4882a593Smuzhiyun exit:
682*4882a593Smuzhiyun if (temp1) {
683*4882a593Smuzhiyun acpi_os_free(temp1);
684*4882a593Smuzhiyun }
685*4882a593Smuzhiyun if (temp2) {
686*4882a593Smuzhiyun acpi_os_free(temp2);
687*4882a593Smuzhiyun }
688*4882a593Smuzhiyun if (temp3) {
689*4882a593Smuzhiyun acpi_os_free(temp3);
690*4882a593Smuzhiyun }
691*4882a593Smuzhiyun return (status);
692*4882a593Smuzhiyun }
693*4882a593Smuzhiyun
694*4882a593Smuzhiyun /*******************************************************************************
695*4882a593Smuzhiyun *
696*4882a593Smuzhiyun * FUNCTION: acpi_db_test_package_type
697*4882a593Smuzhiyun *
698*4882a593Smuzhiyun * PARAMETERS: node - Parent NS node for the object
699*4882a593Smuzhiyun *
700*4882a593Smuzhiyun * RETURN: Status
701*4882a593Smuzhiyun *
702*4882a593Smuzhiyun * DESCRIPTION: Test read for a Package object.
703*4882a593Smuzhiyun *
704*4882a593Smuzhiyun ******************************************************************************/
705*4882a593Smuzhiyun
acpi_db_test_package_type(struct acpi_namespace_node * node)706*4882a593Smuzhiyun static acpi_status acpi_db_test_package_type(struct acpi_namespace_node *node)
707*4882a593Smuzhiyun {
708*4882a593Smuzhiyun union acpi_object *temp1 = NULL;
709*4882a593Smuzhiyun acpi_status status;
710*4882a593Smuzhiyun
711*4882a593Smuzhiyun /* Read the original value */
712*4882a593Smuzhiyun
713*4882a593Smuzhiyun status = acpi_db_read_from_object(node, ACPI_TYPE_PACKAGE, &temp1);
714*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
715*4882a593Smuzhiyun return (status);
716*4882a593Smuzhiyun }
717*4882a593Smuzhiyun
718*4882a593Smuzhiyun acpi_os_printf(" %.2X Elements", temp1->package.count);
719*4882a593Smuzhiyun acpi_os_free(temp1);
720*4882a593Smuzhiyun return (status);
721*4882a593Smuzhiyun }
722*4882a593Smuzhiyun
723*4882a593Smuzhiyun /*******************************************************************************
724*4882a593Smuzhiyun *
725*4882a593Smuzhiyun * FUNCTION: acpi_db_test_field_unit_type
726*4882a593Smuzhiyun *
727*4882a593Smuzhiyun * PARAMETERS: obj_desc - A field unit object
728*4882a593Smuzhiyun *
729*4882a593Smuzhiyun * RETURN: Status
730*4882a593Smuzhiyun *
731*4882a593Smuzhiyun * DESCRIPTION: Test read/write on a named field unit.
732*4882a593Smuzhiyun *
733*4882a593Smuzhiyun ******************************************************************************/
734*4882a593Smuzhiyun
735*4882a593Smuzhiyun static acpi_status
acpi_db_test_field_unit_type(union acpi_operand_object * obj_desc)736*4882a593Smuzhiyun acpi_db_test_field_unit_type(union acpi_operand_object *obj_desc)
737*4882a593Smuzhiyun {
738*4882a593Smuzhiyun union acpi_operand_object *region_obj;
739*4882a593Smuzhiyun u32 bit_length = 0;
740*4882a593Smuzhiyun u32 byte_length = 0;
741*4882a593Smuzhiyun acpi_status status = AE_OK;
742*4882a593Smuzhiyun union acpi_operand_object *ret_buffer_desc;
743*4882a593Smuzhiyun
744*4882a593Smuzhiyun /* Supported spaces are memory/io/pci_config */
745*4882a593Smuzhiyun
746*4882a593Smuzhiyun region_obj = obj_desc->field.region_obj;
747*4882a593Smuzhiyun switch (region_obj->region.space_id) {
748*4882a593Smuzhiyun case ACPI_ADR_SPACE_SYSTEM_MEMORY:
749*4882a593Smuzhiyun case ACPI_ADR_SPACE_SYSTEM_IO:
750*4882a593Smuzhiyun case ACPI_ADR_SPACE_PCI_CONFIG:
751*4882a593Smuzhiyun
752*4882a593Smuzhiyun /* Need the interpreter to execute */
753*4882a593Smuzhiyun
754*4882a593Smuzhiyun acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
755*4882a593Smuzhiyun acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
756*4882a593Smuzhiyun
757*4882a593Smuzhiyun /* Exercise read-then-write */
758*4882a593Smuzhiyun
759*4882a593Smuzhiyun status =
760*4882a593Smuzhiyun acpi_ex_read_data_from_field(NULL, obj_desc,
761*4882a593Smuzhiyun &ret_buffer_desc);
762*4882a593Smuzhiyun if (status == AE_OK) {
763*4882a593Smuzhiyun acpi_ex_write_data_to_field(ret_buffer_desc, obj_desc,
764*4882a593Smuzhiyun NULL);
765*4882a593Smuzhiyun acpi_ut_remove_reference(ret_buffer_desc);
766*4882a593Smuzhiyun }
767*4882a593Smuzhiyun
768*4882a593Smuzhiyun acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
769*4882a593Smuzhiyun acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
770*4882a593Smuzhiyun
771*4882a593Smuzhiyun bit_length = obj_desc->common_field.bit_length;
772*4882a593Smuzhiyun byte_length = ACPI_ROUND_BITS_UP_TO_BYTES(bit_length);
773*4882a593Smuzhiyun
774*4882a593Smuzhiyun acpi_os_printf(ACPI_DEBUG_LENGTH_FORMAT " [%s]", bit_length,
775*4882a593Smuzhiyun byte_length,
776*4882a593Smuzhiyun acpi_ut_get_region_name(region_obj->region.
777*4882a593Smuzhiyun space_id));
778*4882a593Smuzhiyun return (status);
779*4882a593Smuzhiyun
780*4882a593Smuzhiyun default:
781*4882a593Smuzhiyun
782*4882a593Smuzhiyun acpi_os_printf
783*4882a593Smuzhiyun (" %s address space is not supported in this command [%4.4s]",
784*4882a593Smuzhiyun acpi_ut_get_region_name(region_obj->region.space_id),
785*4882a593Smuzhiyun region_obj->region.node->name.ascii);
786*4882a593Smuzhiyun return (AE_OK);
787*4882a593Smuzhiyun }
788*4882a593Smuzhiyun }
789*4882a593Smuzhiyun
790*4882a593Smuzhiyun /*******************************************************************************
791*4882a593Smuzhiyun *
792*4882a593Smuzhiyun * FUNCTION: acpi_db_read_from_object
793*4882a593Smuzhiyun *
794*4882a593Smuzhiyun * PARAMETERS: node - Parent NS node for the object
795*4882a593Smuzhiyun * expected_type - Object type expected from the read
796*4882a593Smuzhiyun * value - Where the value read is returned
797*4882a593Smuzhiyun *
798*4882a593Smuzhiyun * RETURN: Status
799*4882a593Smuzhiyun *
800*4882a593Smuzhiyun * DESCRIPTION: Performs a read from the specified object by invoking the
801*4882a593Smuzhiyun * special debugger control method that reads the object. Thus,
802*4882a593Smuzhiyun * the AML interpreter is doing all of the work, increasing the
803*4882a593Smuzhiyun * validity of the test.
804*4882a593Smuzhiyun *
805*4882a593Smuzhiyun ******************************************************************************/
806*4882a593Smuzhiyun
807*4882a593Smuzhiyun static acpi_status
acpi_db_read_from_object(struct acpi_namespace_node * node,acpi_object_type expected_type,union acpi_object ** value)808*4882a593Smuzhiyun acpi_db_read_from_object(struct acpi_namespace_node *node,
809*4882a593Smuzhiyun acpi_object_type expected_type,
810*4882a593Smuzhiyun union acpi_object **value)
811*4882a593Smuzhiyun {
812*4882a593Smuzhiyun union acpi_object *ret_value;
813*4882a593Smuzhiyun struct acpi_object_list param_objects;
814*4882a593Smuzhiyun union acpi_object params[2];
815*4882a593Smuzhiyun struct acpi_buffer return_obj;
816*4882a593Smuzhiyun acpi_status status;
817*4882a593Smuzhiyun
818*4882a593Smuzhiyun params[0].type = ACPI_TYPE_LOCAL_REFERENCE;
819*4882a593Smuzhiyun params[0].reference.actual_type = node->type;
820*4882a593Smuzhiyun params[0].reference.handle = ACPI_CAST_PTR(acpi_handle, node);
821*4882a593Smuzhiyun
822*4882a593Smuzhiyun param_objects.count = 1;
823*4882a593Smuzhiyun param_objects.pointer = params;
824*4882a593Smuzhiyun
825*4882a593Smuzhiyun return_obj.length = ACPI_ALLOCATE_BUFFER;
826*4882a593Smuzhiyun
827*4882a593Smuzhiyun acpi_gbl_method_executing = TRUE;
828*4882a593Smuzhiyun status = acpi_evaluate_object(read_handle, NULL,
829*4882a593Smuzhiyun ¶m_objects, &return_obj);
830*4882a593Smuzhiyun
831*4882a593Smuzhiyun acpi_gbl_method_executing = FALSE;
832*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
833*4882a593Smuzhiyun acpi_os_printf("Could not read from object, %s",
834*4882a593Smuzhiyun acpi_format_exception(status));
835*4882a593Smuzhiyun return (status);
836*4882a593Smuzhiyun }
837*4882a593Smuzhiyun
838*4882a593Smuzhiyun ret_value = (union acpi_object *)return_obj.pointer;
839*4882a593Smuzhiyun
840*4882a593Smuzhiyun switch (ret_value->type) {
841*4882a593Smuzhiyun case ACPI_TYPE_INTEGER:
842*4882a593Smuzhiyun case ACPI_TYPE_BUFFER:
843*4882a593Smuzhiyun case ACPI_TYPE_STRING:
844*4882a593Smuzhiyun case ACPI_TYPE_PACKAGE:
845*4882a593Smuzhiyun /*
846*4882a593Smuzhiyun * Did we receive the type we wanted? Most important for the
847*4882a593Smuzhiyun * Integer/Buffer case (when a field is larger than an Integer,
848*4882a593Smuzhiyun * it should return a Buffer).
849*4882a593Smuzhiyun */
850*4882a593Smuzhiyun if (ret_value->type != expected_type) {
851*4882a593Smuzhiyun acpi_os_printf
852*4882a593Smuzhiyun (" Type mismatch: Expected %s, Received %s",
853*4882a593Smuzhiyun acpi_ut_get_type_name(expected_type),
854*4882a593Smuzhiyun acpi_ut_get_type_name(ret_value->type));
855*4882a593Smuzhiyun
856*4882a593Smuzhiyun acpi_os_free(return_obj.pointer);
857*4882a593Smuzhiyun return (AE_TYPE);
858*4882a593Smuzhiyun }
859*4882a593Smuzhiyun
860*4882a593Smuzhiyun *value = ret_value;
861*4882a593Smuzhiyun break;
862*4882a593Smuzhiyun
863*4882a593Smuzhiyun default:
864*4882a593Smuzhiyun
865*4882a593Smuzhiyun acpi_os_printf(" Unsupported return object type, %s",
866*4882a593Smuzhiyun acpi_ut_get_type_name(ret_value->type));
867*4882a593Smuzhiyun
868*4882a593Smuzhiyun acpi_os_free(return_obj.pointer);
869*4882a593Smuzhiyun return (AE_TYPE);
870*4882a593Smuzhiyun }
871*4882a593Smuzhiyun
872*4882a593Smuzhiyun return (status);
873*4882a593Smuzhiyun }
874*4882a593Smuzhiyun
875*4882a593Smuzhiyun /*******************************************************************************
876*4882a593Smuzhiyun *
877*4882a593Smuzhiyun * FUNCTION: acpi_db_write_to_object
878*4882a593Smuzhiyun *
879*4882a593Smuzhiyun * PARAMETERS: node - Parent NS node for the object
880*4882a593Smuzhiyun * value - Value to be written
881*4882a593Smuzhiyun *
882*4882a593Smuzhiyun * RETURN: Status
883*4882a593Smuzhiyun *
884*4882a593Smuzhiyun * DESCRIPTION: Performs a write to the specified object by invoking the
885*4882a593Smuzhiyun * special debugger control method that writes the object. Thus,
886*4882a593Smuzhiyun * the AML interpreter is doing all of the work, increasing the
887*4882a593Smuzhiyun * validity of the test.
888*4882a593Smuzhiyun *
889*4882a593Smuzhiyun ******************************************************************************/
890*4882a593Smuzhiyun
891*4882a593Smuzhiyun static acpi_status
acpi_db_write_to_object(struct acpi_namespace_node * node,union acpi_object * value)892*4882a593Smuzhiyun acpi_db_write_to_object(struct acpi_namespace_node *node,
893*4882a593Smuzhiyun union acpi_object *value)
894*4882a593Smuzhiyun {
895*4882a593Smuzhiyun struct acpi_object_list param_objects;
896*4882a593Smuzhiyun union acpi_object params[2];
897*4882a593Smuzhiyun acpi_status status;
898*4882a593Smuzhiyun
899*4882a593Smuzhiyun params[0].type = ACPI_TYPE_LOCAL_REFERENCE;
900*4882a593Smuzhiyun params[0].reference.actual_type = node->type;
901*4882a593Smuzhiyun params[0].reference.handle = ACPI_CAST_PTR(acpi_handle, node);
902*4882a593Smuzhiyun
903*4882a593Smuzhiyun /* Copy the incoming user parameter */
904*4882a593Smuzhiyun
905*4882a593Smuzhiyun memcpy(¶ms[1], value, sizeof(union acpi_object));
906*4882a593Smuzhiyun
907*4882a593Smuzhiyun param_objects.count = 2;
908*4882a593Smuzhiyun param_objects.pointer = params;
909*4882a593Smuzhiyun
910*4882a593Smuzhiyun acpi_gbl_method_executing = TRUE;
911*4882a593Smuzhiyun status = acpi_evaluate_object(write_handle, NULL, ¶m_objects, NULL);
912*4882a593Smuzhiyun acpi_gbl_method_executing = FALSE;
913*4882a593Smuzhiyun
914*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
915*4882a593Smuzhiyun acpi_os_printf("Could not write to object, %s",
916*4882a593Smuzhiyun acpi_format_exception(status));
917*4882a593Smuzhiyun }
918*4882a593Smuzhiyun
919*4882a593Smuzhiyun return (status);
920*4882a593Smuzhiyun }
921*4882a593Smuzhiyun
922*4882a593Smuzhiyun /*******************************************************************************
923*4882a593Smuzhiyun *
924*4882a593Smuzhiyun * FUNCTION: acpi_db_evaluate_all_predefined_names
925*4882a593Smuzhiyun *
926*4882a593Smuzhiyun * PARAMETERS: count_arg - Max number of methods to execute
927*4882a593Smuzhiyun *
928*4882a593Smuzhiyun * RETURN: None
929*4882a593Smuzhiyun *
930*4882a593Smuzhiyun * DESCRIPTION: Namespace batch execution. Execute predefined names in the
931*4882a593Smuzhiyun * namespace, up to the max count, if specified.
932*4882a593Smuzhiyun *
933*4882a593Smuzhiyun ******************************************************************************/
934*4882a593Smuzhiyun
acpi_db_evaluate_all_predefined_names(char * count_arg)935*4882a593Smuzhiyun static void acpi_db_evaluate_all_predefined_names(char *count_arg)
936*4882a593Smuzhiyun {
937*4882a593Smuzhiyun struct acpi_db_execute_walk info;
938*4882a593Smuzhiyun
939*4882a593Smuzhiyun info.count = 0;
940*4882a593Smuzhiyun info.max_count = ACPI_UINT32_MAX;
941*4882a593Smuzhiyun
942*4882a593Smuzhiyun if (count_arg) {
943*4882a593Smuzhiyun info.max_count = strtoul(count_arg, NULL, 0);
944*4882a593Smuzhiyun }
945*4882a593Smuzhiyun
946*4882a593Smuzhiyun /* Search all nodes in namespace */
947*4882a593Smuzhiyun
948*4882a593Smuzhiyun (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
949*4882a593Smuzhiyun ACPI_UINT32_MAX,
950*4882a593Smuzhiyun acpi_db_evaluate_one_predefined_name, NULL,
951*4882a593Smuzhiyun (void *)&info, NULL);
952*4882a593Smuzhiyun
953*4882a593Smuzhiyun acpi_os_printf("Evaluated %u predefined names in the namespace\n",
954*4882a593Smuzhiyun info.count);
955*4882a593Smuzhiyun }
956*4882a593Smuzhiyun
957*4882a593Smuzhiyun /*******************************************************************************
958*4882a593Smuzhiyun *
959*4882a593Smuzhiyun * FUNCTION: acpi_db_evaluate_one_predefined_name
960*4882a593Smuzhiyun *
961*4882a593Smuzhiyun * PARAMETERS: Callback from walk_namespace
962*4882a593Smuzhiyun *
963*4882a593Smuzhiyun * RETURN: Status
964*4882a593Smuzhiyun *
965*4882a593Smuzhiyun * DESCRIPTION: Batch execution module. Currently only executes predefined
966*4882a593Smuzhiyun * ACPI names.
967*4882a593Smuzhiyun *
968*4882a593Smuzhiyun ******************************************************************************/
969*4882a593Smuzhiyun
970*4882a593Smuzhiyun static acpi_status
acpi_db_evaluate_one_predefined_name(acpi_handle obj_handle,u32 nesting_level,void * context,void ** return_value)971*4882a593Smuzhiyun acpi_db_evaluate_one_predefined_name(acpi_handle obj_handle,
972*4882a593Smuzhiyun u32 nesting_level,
973*4882a593Smuzhiyun void *context, void **return_value)
974*4882a593Smuzhiyun {
975*4882a593Smuzhiyun struct acpi_namespace_node *node =
976*4882a593Smuzhiyun (struct acpi_namespace_node *)obj_handle;
977*4882a593Smuzhiyun struct acpi_db_execute_walk *info =
978*4882a593Smuzhiyun (struct acpi_db_execute_walk *)context;
979*4882a593Smuzhiyun char *pathname;
980*4882a593Smuzhiyun const union acpi_predefined_info *predefined;
981*4882a593Smuzhiyun struct acpi_device_info *obj_info;
982*4882a593Smuzhiyun struct acpi_object_list param_objects;
983*4882a593Smuzhiyun union acpi_object params[ACPI_METHOD_NUM_ARGS];
984*4882a593Smuzhiyun union acpi_object *this_param;
985*4882a593Smuzhiyun struct acpi_buffer return_obj;
986*4882a593Smuzhiyun acpi_status status;
987*4882a593Smuzhiyun u16 arg_type_list;
988*4882a593Smuzhiyun u8 arg_count;
989*4882a593Smuzhiyun u8 arg_type;
990*4882a593Smuzhiyun u32 i;
991*4882a593Smuzhiyun
992*4882a593Smuzhiyun /* The name must be a predefined ACPI name */
993*4882a593Smuzhiyun
994*4882a593Smuzhiyun predefined = acpi_ut_match_predefined_method(node->name.ascii);
995*4882a593Smuzhiyun if (!predefined) {
996*4882a593Smuzhiyun return (AE_OK);
997*4882a593Smuzhiyun }
998*4882a593Smuzhiyun
999*4882a593Smuzhiyun if (node->type == ACPI_TYPE_LOCAL_SCOPE) {
1000*4882a593Smuzhiyun return (AE_OK);
1001*4882a593Smuzhiyun }
1002*4882a593Smuzhiyun
1003*4882a593Smuzhiyun pathname = acpi_ns_get_normalized_pathname(node, TRUE);
1004*4882a593Smuzhiyun if (!pathname) {
1005*4882a593Smuzhiyun return (AE_OK);
1006*4882a593Smuzhiyun }
1007*4882a593Smuzhiyun
1008*4882a593Smuzhiyun /* Get the object info for number of method parameters */
1009*4882a593Smuzhiyun
1010*4882a593Smuzhiyun status = acpi_get_object_info(obj_handle, &obj_info);
1011*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
1012*4882a593Smuzhiyun ACPI_FREE(pathname);
1013*4882a593Smuzhiyun return (status);
1014*4882a593Smuzhiyun }
1015*4882a593Smuzhiyun
1016*4882a593Smuzhiyun param_objects.count = 0;
1017*4882a593Smuzhiyun param_objects.pointer = NULL;
1018*4882a593Smuzhiyun
1019*4882a593Smuzhiyun if (obj_info->type == ACPI_TYPE_METHOD) {
1020*4882a593Smuzhiyun
1021*4882a593Smuzhiyun /* Setup default parameters (with proper types) */
1022*4882a593Smuzhiyun
1023*4882a593Smuzhiyun arg_type_list = predefined->info.argument_list;
1024*4882a593Smuzhiyun arg_count = METHOD_GET_ARG_COUNT(arg_type_list);
1025*4882a593Smuzhiyun
1026*4882a593Smuzhiyun /*
1027*4882a593Smuzhiyun * Setup the ACPI-required number of arguments, regardless of what
1028*4882a593Smuzhiyun * the actual method defines. If there is a difference, then the
1029*4882a593Smuzhiyun * method is wrong and a warning will be issued during execution.
1030*4882a593Smuzhiyun */
1031*4882a593Smuzhiyun this_param = params;
1032*4882a593Smuzhiyun for (i = 0; i < arg_count; i++) {
1033*4882a593Smuzhiyun arg_type = METHOD_GET_NEXT_TYPE(arg_type_list);
1034*4882a593Smuzhiyun this_param->type = arg_type;
1035*4882a593Smuzhiyun
1036*4882a593Smuzhiyun switch (arg_type) {
1037*4882a593Smuzhiyun case ACPI_TYPE_INTEGER:
1038*4882a593Smuzhiyun
1039*4882a593Smuzhiyun this_param->integer.value = 1;
1040*4882a593Smuzhiyun break;
1041*4882a593Smuzhiyun
1042*4882a593Smuzhiyun case ACPI_TYPE_STRING:
1043*4882a593Smuzhiyun
1044*4882a593Smuzhiyun this_param->string.pointer =
1045*4882a593Smuzhiyun "This is the default argument string";
1046*4882a593Smuzhiyun this_param->string.length =
1047*4882a593Smuzhiyun strlen(this_param->string.pointer);
1048*4882a593Smuzhiyun break;
1049*4882a593Smuzhiyun
1050*4882a593Smuzhiyun case ACPI_TYPE_BUFFER:
1051*4882a593Smuzhiyun
1052*4882a593Smuzhiyun this_param->buffer.pointer = (u8 *)params; /* just a garbage buffer */
1053*4882a593Smuzhiyun this_param->buffer.length = 48;
1054*4882a593Smuzhiyun break;
1055*4882a593Smuzhiyun
1056*4882a593Smuzhiyun case ACPI_TYPE_PACKAGE:
1057*4882a593Smuzhiyun
1058*4882a593Smuzhiyun this_param->package.elements = NULL;
1059*4882a593Smuzhiyun this_param->package.count = 0;
1060*4882a593Smuzhiyun break;
1061*4882a593Smuzhiyun
1062*4882a593Smuzhiyun default:
1063*4882a593Smuzhiyun
1064*4882a593Smuzhiyun acpi_os_printf
1065*4882a593Smuzhiyun ("%s: Unsupported argument type: %u\n",
1066*4882a593Smuzhiyun pathname, arg_type);
1067*4882a593Smuzhiyun break;
1068*4882a593Smuzhiyun }
1069*4882a593Smuzhiyun
1070*4882a593Smuzhiyun this_param++;
1071*4882a593Smuzhiyun }
1072*4882a593Smuzhiyun
1073*4882a593Smuzhiyun param_objects.count = arg_count;
1074*4882a593Smuzhiyun param_objects.pointer = params;
1075*4882a593Smuzhiyun }
1076*4882a593Smuzhiyun
1077*4882a593Smuzhiyun ACPI_FREE(obj_info);
1078*4882a593Smuzhiyun return_obj.pointer = NULL;
1079*4882a593Smuzhiyun return_obj.length = ACPI_ALLOCATE_BUFFER;
1080*4882a593Smuzhiyun
1081*4882a593Smuzhiyun /* Do the actual method execution */
1082*4882a593Smuzhiyun
1083*4882a593Smuzhiyun acpi_gbl_method_executing = TRUE;
1084*4882a593Smuzhiyun
1085*4882a593Smuzhiyun status = acpi_evaluate_object(node, NULL, ¶m_objects, &return_obj);
1086*4882a593Smuzhiyun
1087*4882a593Smuzhiyun acpi_os_printf("%-32s returned %s\n",
1088*4882a593Smuzhiyun pathname, acpi_format_exception(status));
1089*4882a593Smuzhiyun acpi_gbl_method_executing = FALSE;
1090*4882a593Smuzhiyun ACPI_FREE(pathname);
1091*4882a593Smuzhiyun
1092*4882a593Smuzhiyun /* Ignore status from method execution */
1093*4882a593Smuzhiyun
1094*4882a593Smuzhiyun status = AE_OK;
1095*4882a593Smuzhiyun
1096*4882a593Smuzhiyun /* Update count, check if we have executed enough methods */
1097*4882a593Smuzhiyun
1098*4882a593Smuzhiyun info->count++;
1099*4882a593Smuzhiyun if (info->count >= info->max_count) {
1100*4882a593Smuzhiyun status = AE_CTRL_TERMINATE;
1101*4882a593Smuzhiyun }
1102*4882a593Smuzhiyun
1103*4882a593Smuzhiyun return (status);
1104*4882a593Smuzhiyun }
1105