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