Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
6595 serge 1
/*******************************************************************************
2
 *
3
 * Module Name: dbinput - user front-end to the AML debugger
4
 *
5
 ******************************************************************************/
6
 
7
/*
8
 * Copyright (C) 2000 - 2015, Intel Corp.
9
 * All rights reserved.
10
 *
11
 * Redistribution and use in source and binary forms, with or without
12
 * modification, are permitted provided that the following conditions
13
 * are met:
14
 * 1. Redistributions of source code must retain the above copyright
15
 *    notice, this list of conditions, and the following disclaimer,
16
 *    without modification.
17
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18
 *    substantially similar to the "NO WARRANTY" disclaimer below
19
 *    ("Disclaimer") and any redistribution must be conditioned upon
20
 *    including a substantially similar Disclaimer requirement for further
21
 *    binary redistribution.
22
 * 3. Neither the names of the above-listed copyright holders nor the names
23
 *    of any contributors may be used to endorse or promote products derived
24
 *    from this software without specific prior written permission.
25
 *
26
 * Alternatively, this software may be distributed under the terms of the
27
 * GNU General Public License ("GPL") version 2 as published by the Free
28
 * Software Foundation.
29
 *
30
 * NO WARRANTY
31
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41
 * POSSIBILITY OF SUCH DAMAGES.
42
 */
43
 
44
#include 
45
#include "accommon.h"
46
#include "acdebug.h"
47
 
48
#define _COMPONENT          ACPI_CA_DEBUGGER
49
ACPI_MODULE_NAME("dbinput")
50
 
51
/* Local prototypes */
52
static u32 acpi_db_get_line(char *input_buffer);
53
 
54
static u32 acpi_db_match_command(char *user_command);
55
 
56
static void acpi_db_single_thread(void);
57
 
58
static void acpi_db_display_command_info(char *command, u8 display_all);
59
 
60
static void acpi_db_display_help(char *command);
61
 
62
static u8
63
acpi_db_match_command_help(char *command,
64
			   const struct acpi_db_command_help *help);
65
 
66
/*
67
 * Top-level debugger commands.
68
 *
69
 * This list of commands must match the string table below it
70
 */
71
enum acpi_ex_debugger_commands {
72
	CMD_NOT_FOUND = 0,
73
	CMD_NULL,
74
	CMD_ALLOCATIONS,
75
	CMD_ARGS,
76
	CMD_ARGUMENTS,
77
	CMD_BREAKPOINT,
78
	CMD_BUSINFO,
79
	CMD_CALL,
80
	CMD_DEBUG,
81
	CMD_DISASSEMBLE,
82
	CMD_DISASM,
83
	CMD_DUMP,
84
	CMD_EVALUATE,
85
	CMD_EXECUTE,
86
	CMD_EXIT,
87
	CMD_FIND,
88
	CMD_GO,
89
	CMD_HANDLERS,
90
	CMD_HELP,
91
	CMD_HELP2,
92
	CMD_HISTORY,
93
	CMD_HISTORY_EXE,
94
	CMD_HISTORY_LAST,
95
	CMD_INFORMATION,
96
	CMD_INTEGRITY,
97
	CMD_INTO,
98
	CMD_LEVEL,
99
	CMD_LIST,
100
	CMD_LOCALS,
101
	CMD_LOCKS,
102
	CMD_METHODS,
103
	CMD_NAMESPACE,
104
	CMD_NOTIFY,
105
	CMD_OBJECTS,
106
	CMD_OSI,
107
	CMD_OWNER,
108
	CMD_PATHS,
109
	CMD_PREDEFINED,
110
	CMD_PREFIX,
111
	CMD_QUIT,
112
	CMD_REFERENCES,
113
	CMD_RESOURCES,
114
	CMD_RESULTS,
115
	CMD_SET,
116
	CMD_STATS,
117
	CMD_STOP,
118
	CMD_TABLES,
119
	CMD_TEMPLATE,
120
	CMD_TRACE,
121
	CMD_TREE,
122
	CMD_TYPE,
123
#ifdef ACPI_APPLICATION
124
	CMD_ENABLEACPI,
125
	CMD_EVENT,
126
	CMD_GPE,
127
	CMD_GPES,
128
	CMD_SCI,
129
	CMD_SLEEP,
130
 
131
	CMD_CLOSE,
132
	CMD_LOAD,
133
	CMD_OPEN,
134
	CMD_UNLOAD,
135
 
136
	CMD_TERMINATE,
137
	CMD_THREADS,
138
 
139
	CMD_TEST,
140
#endif
141
};
142
 
143
#define CMD_FIRST_VALID     2
144
 
145
/* Second parameter is the required argument count */
146
 
147
static const struct acpi_db_command_info acpi_gbl_db_commands[] = {
148
	{"", 0},
149
	{"", 0},
150
	{"ALLOCATIONS", 0},
151
	{"ARGS", 0},
152
	{"ARGUMENTS", 0},
153
	{"BREAKPOINT", 1},
154
	{"BUSINFO", 0},
155
	{"CALL", 0},
156
	{"DEBUG", 1},
157
	{"DISASSEMBLE", 1},
158
	{"DISASM", 1},
159
	{"DUMP", 1},
160
	{"EVALUATE", 1},
161
	{"EXECUTE", 1},
162
	{"EXIT", 0},
163
	{"FIND", 1},
164
	{"GO", 0},
165
	{"HANDLERS", 0},
166
	{"HELP", 0},
167
	{"?", 0},
168
	{"HISTORY", 0},
169
	{"!", 1},
170
	{"!!", 0},
171
	{"INFORMATION", 0},
172
	{"INTEGRITY", 0},
173
	{"INTO", 0},
174
	{"LEVEL", 0},
175
	{"LIST", 0},
176
	{"LOCALS", 0},
177
	{"LOCKS", 0},
178
	{"METHODS", 0},
179
	{"NAMESPACE", 0},
180
	{"NOTIFY", 2},
181
	{"OBJECTS", 0},
182
	{"OSI", 0},
183
	{"OWNER", 1},
184
	{"PATHS", 0},
185
	{"PREDEFINED", 0},
186
	{"PREFIX", 0},
187
	{"QUIT", 0},
188
	{"REFERENCES", 1},
189
	{"RESOURCES", 0},
190
	{"RESULTS", 0},
191
	{"SET", 3},
192
	{"STATS", 1},
193
	{"STOP", 0},
194
	{"TABLES", 0},
195
	{"TEMPLATE", 1},
196
	{"TRACE", 1},
197
	{"TREE", 0},
198
	{"TYPE", 1},
199
#ifdef ACPI_APPLICATION
200
	{"ENABLEACPI", 0},
201
	{"EVENT", 1},
202
	{"GPE", 1},
203
	{"GPES", 0},
204
	{"SCI", 0},
205
	{"SLEEP", 0},
206
 
207
	{"CLOSE", 0},
208
	{"LOAD", 1},
209
	{"OPEN", 1},
210
	{"UNLOAD", 1},
211
 
212
	{"TERMINATE", 0},
213
	{"THREADS", 3},
214
 
215
	{"TEST", 1},
216
#endif
217
	{NULL, 0}
218
};
219
 
220
/*
221
 * Help for all debugger commands. First argument is the number of lines
222
 * of help to output for the command.
223
 */
224
static const struct acpi_db_command_help acpi_gbl_db_command_help[] = {
225
	{0, "\nGeneral-Purpose Commands:", "\n"},
226
	{1, "  Allocations", "Display list of current memory allocations\n"},
227
	{2, "  Dump 
|", "\n"},
228
	{0, "       [Byte|Word|Dword|Qword]",
229
	 "Display ACPI objects or memory\n"},
230
	{1, "  Handlers", "Info about global handlers\n"},
231
	{1, "  Help [Command]", "This help screen or individual command\n"},
232
	{1, "  History", "Display command history buffer\n"},
233
	{1, "  Level ] [console]",
234
	 "Get/Set debug level for file or console\n"},
235
	{1, "  Locks", "Current status of internal mutexes\n"},
236
	{1, "  Osi [Install|Remove ]",
237
	 "Display or modify global _OSI list\n"},
238
	{1, "  Quit or Exit", "Exit this command\n"},
239
	{8, "  Stats ",
240
	 "Display namespace and memory statistics\n"},
241
	{1, "     Allocations", "Display list of current memory allocations\n"},
242
	{1, "     Memory", "Dump internal memory lists\n"},
243
	{1, "     Misc", "Namespace search and mutex stats\n"},
244
	{1, "     Objects", "Summary of namespace objects\n"},
245
	{1, "     Sizes", "Sizes for each of the internal objects\n"},
246
	{1, "     Stack", "Display CPU stack usage\n"},
247
	{1, "     Tables", "Info about current ACPI table(s)\n"},
248
	{1, "  Tables", "Display info about loaded ACPI tables\n"},
249
	{1, "  ! ", "Execute command from history buffer\n"},
250
	{1, "  !!", "Execute last command again\n"},
251
 
252
	{0, "\nNamespace Access Commands:", "\n"},
253
	{1, "  Businfo", "Display system bus info\n"},
254
	{1, "  Disassemble ", "Disassemble a control method\n"},
255
	{1, "  Find  (? is wildcard)",
256
	 "Find ACPI name(s) with wildcards\n"},
257
	{1, "  Integrity", "Validate namespace integrity\n"},
258
	{1, "  Methods", "Display list of loaded control methods\n"},
259
	{1, "  Namespace [Object] [Depth]",
260
	 "Display loaded namespace tree/subtree\n"},
261
	{1, "  Notify  ", "Send a notification on Object\n"},
262
	{1, "  Objects [ObjectType]",
263
	 "Display summary of all objects or just given type\n"},
264
	{1, "  Owner  [Depth]",
265
	 "Display loaded namespace by object owner\n"},
266
	{1, "  Paths", "Display full pathnames of namespace objects\n"},
267
	{1, "  Predefined", "Check all predefined names\n"},
268
	{1, "  Prefix []", "Set or Get current execution prefix\n"},
269
	{1, "  References ", "Find all references to object at addr\n"},
270
	{1, "  Resources [DeviceName]",
271
	 "Display Device resources (no arg = all devices)\n"},
272
	{1, "  Set N  ", "Set value for named integer\n"},
273
	{1, "  Template ", "Format/dump a Buffer/ResourceTemplate\n"},
274
	{1, "  Type ", "Display object type\n"},
275
 
276
	{0, "\nControl Method Execution Commands:", "\n"},
277
	{1, "  Arguments (or Args)", "Display method arguments\n"},
278
	{1, "  Breakpoint ", "Set an AML execution breakpoint\n"},
279
	{1, "  Call", "Run to next control method invocation\n"},
280
	{1, "  Debug  [Arguments]", "Single Step a control method\n"},
281
	{6, "  Evaluate", "Synonym for Execute\n"},
282
	{5, "  Execute  [Arguments]", "Execute control method\n"},
283
	{1, "     Hex Integer", "Integer method argument\n"},
284
	{1, "     \"Ascii String\"", "String method argument\n"},
285
	{1, "     (Hex Byte List)", "Buffer method argument\n"},
286
	{1, "     [Package Element List]", "Package method argument\n"},
287
	{1, "  Go", "Allow method to run to completion\n"},
288
	{1, "  Information", "Display info about the current method\n"},
289
	{1, "  Into", "Step into (not over) a method call\n"},
290
	{1, "  List [# of Aml Opcodes]", "Display method ASL statements\n"},
291
	{1, "  Locals", "Display method local variables\n"},
292
	{1, "  Results", "Display method result stack\n"},
293
	{1, "  Set  <#> ", "Set method data (Arguments/Locals)\n"},
294
	{1, "  Stop", "Terminate control method\n"},
295
	{5, "  Trace  [] [Once]",
296
	 "Trace control method execution\n"},
297
	{1, "     Enable", "Enable all messages\n"},
298
	{1, "     Disable", "Disable tracing\n"},
299
	{1, "     Method", "Enable method execution messages\n"},
300
	{1, "     Opcode", "Enable opcode execution messages\n"},
301
	{1, "  Tree", "Display control method calling tree\n"},
302
	{1, "  ", "Single step next AML opcode (over calls)\n"},
303
 
304
#ifdef ACPI_APPLICATION
305
	{0, "\nHardware Simulation Commands:", "\n"},
306
	{1, "  EnableAcpi", "Enable ACPI (hardware) mode\n"},
307
	{1, "  Event  ", "Generate AcpiEvent (Fixed/GPE)\n"},
308
	{1, "  Gpe  [GpeBlockDevice]", "Simulate a GPE\n"},
309
	{1, "  Gpes", "Display info on all GPE devices\n"},
310
	{1, "  Sci", "Generate an SCI\n"},
311
	{1, "  Sleep [SleepState]", "Simulate sleep/wake sequence(s) (0-5)\n"},
312
 
313
	{0, "\nFile I/O Commands:", "\n"},
314
	{1, "  Close", "Close debug output file\n"},
315
	{1, "  Load ", "Load ACPI table from a file\n"},
316
	{1, "  Open ", "Open a file for debug output\n"},
317
	{1, "  Unload ",
318
	 "Unload an ACPI table via namespace object\n"},
319
 
320
	{0, "\nUser Space Commands:", "\n"},
321
	{1, "  Terminate", "Delete namespace and all internal objects\n"},
322
	{1, "  Thread ",
323
	 "Spawn threads to execute method(s)\n"},
324
 
325
	{0, "\nDebug Test Commands:", "\n"},
326
	{3, "  Test ", "Invoke a debug test\n"},
327
	{1, "     Objects", "Read/write/compare all namespace data objects\n"},
328
	{1, "     Predefined",
329
	 "Execute all ACPI predefined names (_STA, etc.)\n"},
330
#endif
331
	{0, NULL, NULL}
332
};
333
 
334
/*******************************************************************************
335
 *
336
 * FUNCTION:    acpi_db_match_command_help
337
 *
338
 * PARAMETERS:  command             - Command string to match
339
 *              help                - Help table entry to attempt match
340
 *
341
 * RETURN:      TRUE if command matched, FALSE otherwise
342
 *
343
 * DESCRIPTION: Attempt to match a command in the help table in order to
344
 *              print help information for a single command.
345
 *
346
 ******************************************************************************/
347
 
348
static u8
349
acpi_db_match_command_help(char *command,
350
			   const struct acpi_db_command_help *help)
351
{
352
	char *invocation = help->invocation;
353
	u32 line_count;
354
 
355
	/* Valid commands in the help table begin with a couple of spaces */
356
 
357
	if (*invocation != ' ') {
358
		return (FALSE);
359
	}
360
 
361
	while (*invocation == ' ') {
362
		invocation++;
363
	}
364
 
365
	/* Match command name (full command or substring) */
366
 
367
	while ((*command) && (*invocation) && (*invocation != ' ')) {
368
		if (tolower((int)*command) != tolower((int)*invocation)) {
369
			return (FALSE);
370
		}
371
 
372
		invocation++;
373
		command++;
374
	}
375
 
376
	/* Print the appropriate number of help lines */
377
 
378
	line_count = help->line_count;
379
	while (line_count) {
380
		acpi_os_printf("%-38s : %s", help->invocation,
381
			       help->description);
382
		help++;
383
		line_count--;
384
	}
385
 
386
	return (TRUE);
387
}
388
 
389
/*******************************************************************************
390
 *
391
 * FUNCTION:    acpi_db_display_command_info
392
 *
393
 * PARAMETERS:  command             - Command string to match
394
 *              display_all         - Display all matching commands, or just
395
 *                                    the first one (substring match)
396
 *
397
 * RETURN:      None
398
 *
399
 * DESCRIPTION: Display help information for a Debugger command.
400
 *
401
 ******************************************************************************/
402
 
403
static void acpi_db_display_command_info(char *command, u8 display_all)
404
{
405
	const struct acpi_db_command_help *next;
406
	u8 matched;
407
 
408
	next = acpi_gbl_db_command_help;
409
	while (next->invocation) {
410
		matched = acpi_db_match_command_help(command, next);
411
		if (!display_all && matched) {
412
			return;
413
		}
414
 
415
		next++;
416
	}
417
}
418
 
419
/*******************************************************************************
420
 *
421
 * FUNCTION:    acpi_db_display_help
422
 *
423
 * PARAMETERS:  command             - Optional command string to display help.
424
 *                                    if not specified, all debugger command
425
 *                                    help strings are displayed
426
 *
427
 * RETURN:      None
428
 *
429
 * DESCRIPTION: Display help for a single debugger command, or all of them.
430
 *
431
 ******************************************************************************/
432
 
433
static void acpi_db_display_help(char *command)
434
{
435
	const struct acpi_db_command_help *next = acpi_gbl_db_command_help;
436
 
437
	if (!command) {
438
 
439
		/* No argument to help, display help for all commands */
440
 
441
		while (next->invocation) {
442
			acpi_os_printf("%-38s%s", next->invocation,
443
				       next->description);
444
			next++;
445
		}
446
	} else {
447
		/* Display help for all commands that match the subtring */
448
 
449
		acpi_db_display_command_info(command, TRUE);
450
	}
451
}
452
 
453
/*******************************************************************************
454
 *
455
 * FUNCTION:    acpi_db_get_next_token
456
 *
457
 * PARAMETERS:  string          - Command buffer
458
 *              next            - Return value, end of next token
459
 *
460
 * RETURN:      Pointer to the start of the next token.
461
 *
462
 * DESCRIPTION: Command line parsing. Get the next token on the command line
463
 *
464
 ******************************************************************************/
465
 
466
char *acpi_db_get_next_token(char *string,
467
			     char **next, acpi_object_type * return_type)
468
{
469
	char *start;
470
	u32 depth;
471
	acpi_object_type type = ACPI_TYPE_INTEGER;
472
 
473
	/* At end of buffer? */
474
 
475
	if (!string || !(*string)) {
476
		return (NULL);
477
	}
478
 
479
	/* Remove any spaces at the beginning */
480
 
481
	if (*string == ' ') {
482
		while (*string && (*string == ' ')) {
483
			string++;
484
		}
485
 
486
		if (!(*string)) {
487
			return (NULL);
488
		}
489
	}
490
 
491
	switch (*string) {
492
	case '"':
493
 
494
		/* This is a quoted string, scan until closing quote */
495
 
496
		string++;
497
		start = string;
498
		type = ACPI_TYPE_STRING;
499
 
500
		/* Find end of string */
501
 
502
		while (*string && (*string != '"')) {
503
			string++;
504
		}
505
		break;
506
 
507
	case '(':
508
 
509
		/* This is the start of a buffer, scan until closing paren */
510
 
511
		string++;
512
		start = string;
513
		type = ACPI_TYPE_BUFFER;
514
 
515
		/* Find end of buffer */
516
 
517
		while (*string && (*string != ')')) {
518
			string++;
519
		}
520
		break;
521
 
522
	case '[':
523
 
524
		/* This is the start of a package, scan until closing bracket */
525
 
526
		string++;
527
		depth = 1;
528
		start = string;
529
		type = ACPI_TYPE_PACKAGE;
530
 
531
		/* Find end of package (closing bracket) */
532
 
533
		while (*string) {
534
 
535
			/* Handle String package elements */
536
 
537
			if (*string == '"') {
538
				/* Find end of string */
539
 
540
				string++;
541
				while (*string && (*string != '"')) {
542
					string++;
543
				}
544
				if (!(*string)) {
545
					break;
546
				}
547
			} else if (*string == '[') {
548
				depth++;	/* A nested package declaration */
549
			} else if (*string == ']') {
550
				depth--;
551
				if (depth == 0) {	/* Found final package closing bracket */
552
					break;
553
				}
554
			}
555
 
556
			string++;
557
		}
558
		break;
559
 
560
	default:
561
 
562
		start = string;
563
 
564
		/* Find end of token */
565
 
566
		while (*string && (*string != ' ')) {
567
			string++;
568
		}
569
		break;
570
	}
571
 
572
	if (!(*string)) {
573
		*next = NULL;
574
	} else {
575
		*string = 0;
576
		*next = string + 1;
577
	}
578
 
579
	*return_type = type;
580
	return (start);
581
}
582
 
583
/*******************************************************************************
584
 *
585
 * FUNCTION:    acpi_db_get_line
586
 *
587
 * PARAMETERS:  input_buffer        - Command line buffer
588
 *
589
 * RETURN:      Count of arguments to the command
590
 *
591
 * DESCRIPTION: Get the next command line from the user. Gets entire line
592
 *              up to the next newline
593
 *
594
 ******************************************************************************/
595
 
596
static u32 acpi_db_get_line(char *input_buffer)
597
{
598
	u32 i;
599
	u32 count;
600
	char *next;
601
	char *this;
602
 
603
	if (acpi_ut_safe_strcpy
604
	    (acpi_gbl_db_parsed_buf, sizeof(acpi_gbl_db_parsed_buf),
605
	     input_buffer)) {
606
		acpi_os_printf
607
		    ("Buffer overflow while parsing input line (max %u characters)\n",
608
		     sizeof(acpi_gbl_db_parsed_buf));
609
		return (0);
610
	}
611
 
612
	this = acpi_gbl_db_parsed_buf;
613
	for (i = 0; i < ACPI_DEBUGGER_MAX_ARGS; i++) {
614
		acpi_gbl_db_args[i] = acpi_db_get_next_token(this, &next,
615
							     &acpi_gbl_db_arg_types
616
							     [i]);
617
		if (!acpi_gbl_db_args[i]) {
618
			break;
619
		}
620
 
621
		this = next;
622
	}
623
 
624
	/* Uppercase the actual command */
625
 
626
	if (acpi_gbl_db_args[0]) {
627
		acpi_ut_strupr(acpi_gbl_db_args[0]);
628
	}
629
 
630
	count = i;
631
	if (count) {
632
		count--;	/* Number of args only */
633
	}
634
 
635
	return (count);
636
}
637
 
638
/*******************************************************************************
639
 *
640
 * FUNCTION:    acpi_db_match_command
641
 *
642
 * PARAMETERS:  user_command            - User command line
643
 *
644
 * RETURN:      Index into command array, -1 if not found
645
 *
646
 * DESCRIPTION: Search command array for a command match
647
 *
648
 ******************************************************************************/
649
 
650
static u32 acpi_db_match_command(char *user_command)
651
{
652
	u32 i;
653
 
654
	if (!user_command || user_command[0] == 0) {
655
		return (CMD_NULL);
656
	}
657
 
658
	for (i = CMD_FIRST_VALID; acpi_gbl_db_commands[i].name; i++) {
659
		if (strstr(acpi_gbl_db_commands[i].name, user_command) ==
660
		    acpi_gbl_db_commands[i].name) {
661
			return (i);
662
		}
663
	}
664
 
665
	/* Command not recognized */
666
 
667
	return (CMD_NOT_FOUND);
668
}
669
 
670
/*******************************************************************************
671
 *
672
 * FUNCTION:    acpi_db_command_dispatch
673
 *
674
 * PARAMETERS:  input_buffer        - Command line buffer
675
 *              walk_state          - Current walk
676
 *              op                  - Current (executing) parse op
677
 *
678
 * RETURN:      Status
679
 *
680
 * DESCRIPTION: Command dispatcher.
681
 *
682
 ******************************************************************************/
683
 
684
acpi_status
685
acpi_db_command_dispatch(char *input_buffer,
686
			 struct acpi_walk_state * walk_state,
687
			 union acpi_parse_object * op)
688
{
689
	u32 temp;
690
	u32 command_index;
691
	u32 param_count;
692
	char *command_line;
693
	acpi_status status = AE_CTRL_TRUE;
694
 
695
	/* If acpi_terminate has been called, terminate this thread */
696
 
697
	if (acpi_gbl_db_terminate_loop) {
698
		return (AE_CTRL_TERMINATE);
699
	}
700
 
701
	/* Find command and add to the history buffer */
702
 
703
	param_count = acpi_db_get_line(input_buffer);
704
	command_index = acpi_db_match_command(acpi_gbl_db_args[0]);
705
	temp = 0;
706
 
707
	/*
708
	 * We don't want to add the !! command to the history buffer. It
709
	 * would cause an infinite loop because it would always be the
710
	 * previous command.
711
	 */
712
	if (command_index != CMD_HISTORY_LAST) {
713
		acpi_db_add_to_history(input_buffer);
714
	}
715
 
716
	/* Verify that we have the minimum number of params */
717
 
718
	if (param_count < acpi_gbl_db_commands[command_index].min_args) {
719
		acpi_os_printf
720
		    ("%u parameters entered, [%s] requires %u parameters\n",
721
		     param_count, acpi_gbl_db_commands[command_index].name,
722
		     acpi_gbl_db_commands[command_index].min_args);
723
 
724
		acpi_db_display_command_info(acpi_gbl_db_commands
725
					     [command_index].name, FALSE);
726
		return (AE_CTRL_TRUE);
727
	}
728
 
729
	/* Decode and dispatch the command */
730
 
731
	switch (command_index) {
732
	case CMD_NULL:
733
 
734
		if (op) {
735
			return (AE_OK);
736
		}
737
		break;
738
 
739
	case CMD_ALLOCATIONS:
740
 
741
#ifdef ACPI_DBG_TRACK_ALLOCATIONS
742
		acpi_ut_dump_allocations((u32)-1, NULL);
743
#endif
744
		break;
745
 
746
	case CMD_ARGS:
747
	case CMD_ARGUMENTS:
748
 
749
		acpi_db_display_arguments();
750
		break;
751
 
752
	case CMD_BREAKPOINT:
753
 
754
		acpi_db_set_method_breakpoint(acpi_gbl_db_args[1], walk_state,
755
					      op);
756
		break;
757
 
758
	case CMD_BUSINFO:
759
 
760
		acpi_db_get_bus_info();
761
		break;
762
 
763
	case CMD_CALL:
764
 
765
		acpi_db_set_method_call_breakpoint(op);
766
		status = AE_OK;
767
		break;
768
 
769
	case CMD_DEBUG:
770
 
771
		acpi_db_execute(acpi_gbl_db_args[1],
772
				&acpi_gbl_db_args[2], &acpi_gbl_db_arg_types[2],
773
				EX_SINGLE_STEP);
774
		break;
775
 
776
	case CMD_DISASSEMBLE:
777
	case CMD_DISASM:
778
 
779
		(void)acpi_db_disassemble_method(acpi_gbl_db_args[1]);
780
		break;
781
 
782
	case CMD_DUMP:
783
 
784
		acpi_db_decode_and_display_object(acpi_gbl_db_args[1],
785
						  acpi_gbl_db_args[2]);
786
		break;
787
 
788
	case CMD_EVALUATE:
789
	case CMD_EXECUTE:
790
 
791
		acpi_db_execute(acpi_gbl_db_args[1],
792
				&acpi_gbl_db_args[2], &acpi_gbl_db_arg_types[2],
793
				EX_NO_SINGLE_STEP);
794
		break;
795
 
796
	case CMD_FIND:
797
 
798
		status = acpi_db_find_name_in_namespace(acpi_gbl_db_args[1]);
799
		break;
800
 
801
	case CMD_GO:
802
 
803
		acpi_gbl_cm_single_step = FALSE;
804
		return (AE_OK);
805
 
806
	case CMD_HANDLERS:
807
 
808
		acpi_db_display_handlers();
809
		break;
810
 
811
	case CMD_HELP:
812
	case CMD_HELP2:
813
 
814
		acpi_db_display_help(acpi_gbl_db_args[1]);
815
		break;
816
 
817
	case CMD_HISTORY:
818
 
819
		acpi_db_display_history();
820
		break;
821
 
822
	case CMD_HISTORY_EXE:	/* ! command */
823
 
824
		command_line = acpi_db_get_from_history(acpi_gbl_db_args[1]);
825
		if (!command_line) {
826
			return (AE_CTRL_TRUE);
827
		}
828
 
829
		status = acpi_db_command_dispatch(command_line, walk_state, op);
830
		return (status);
831
 
832
	case CMD_HISTORY_LAST:	/* !! command */
833
 
834
		command_line = acpi_db_get_from_history(NULL);
835
		if (!command_line) {
836
			return (AE_CTRL_TRUE);
837
		}
838
 
839
		status = acpi_db_command_dispatch(command_line, walk_state, op);
840
		return (status);
841
 
842
	case CMD_INFORMATION:
843
 
844
		acpi_db_display_method_info(op);
845
		break;
846
 
847
	case CMD_INTEGRITY:
848
 
849
		acpi_db_check_integrity();
850
		break;
851
 
852
	case CMD_INTO:
853
 
854
		if (op) {
855
			acpi_gbl_cm_single_step = TRUE;
856
			return (AE_OK);
857
		}
858
		break;
859
 
860
	case CMD_LEVEL:
861
 
862
		if (param_count == 0) {
863
			acpi_os_printf
864
			    ("Current debug level for file output is:    %8.8lX\n",
865
			     acpi_gbl_db_debug_level);
866
			acpi_os_printf
867
			    ("Current debug level for console output is: %8.8lX\n",
868
			     acpi_gbl_db_console_debug_level);
869
		} else if (param_count == 2) {
870
			temp = acpi_gbl_db_console_debug_level;
871
			acpi_gbl_db_console_debug_level =
872
			    strtoul(acpi_gbl_db_args[1], NULL, 16);
873
			acpi_os_printf
874
			    ("Debug Level for console output was %8.8lX, now %8.8lX\n",
875
			     temp, acpi_gbl_db_console_debug_level);
876
		} else {
877
			temp = acpi_gbl_db_debug_level;
878
			acpi_gbl_db_debug_level =
879
			    strtoul(acpi_gbl_db_args[1], NULL, 16);
880
			acpi_os_printf
881
			    ("Debug Level for file output was %8.8lX, now %8.8lX\n",
882
			     temp, acpi_gbl_db_debug_level);
883
		}
884
		break;
885
 
886
	case CMD_LIST:
887
 
888
		acpi_db_disassemble_aml(acpi_gbl_db_args[1], op);
889
		break;
890
 
891
	case CMD_LOCKS:
892
 
893
		acpi_db_display_locks();
894
		break;
895
 
896
	case CMD_LOCALS:
897
 
898
		acpi_db_display_locals();
899
		break;
900
 
901
	case CMD_METHODS:
902
 
903
		status = acpi_db_display_objects("METHOD", acpi_gbl_db_args[1]);
904
		break;
905
 
906
	case CMD_NAMESPACE:
907
 
908
		acpi_db_dump_namespace(acpi_gbl_db_args[1],
909
				       acpi_gbl_db_args[2]);
910
		break;
911
 
912
	case CMD_NOTIFY:
913
 
914
		temp = strtoul(acpi_gbl_db_args[2], NULL, 0);
915
		acpi_db_send_notify(acpi_gbl_db_args[1], temp);
916
		break;
917
 
918
	case CMD_OBJECTS:
919
 
920
		acpi_ut_strupr(acpi_gbl_db_args[1]);
921
		status =
922
		    acpi_db_display_objects(acpi_gbl_db_args[1],
923
					    acpi_gbl_db_args[2]);
924
		break;
925
 
926
	case CMD_OSI:
927
 
928
		acpi_db_display_interfaces(acpi_gbl_db_args[1],
929
					   acpi_gbl_db_args[2]);
930
		break;
931
 
932
	case CMD_OWNER:
933
 
934
		acpi_db_dump_namespace_by_owner(acpi_gbl_db_args[1],
935
						acpi_gbl_db_args[2]);
936
		break;
937
 
938
	case CMD_PATHS:
939
 
940
		acpi_db_dump_namespace_paths();
941
		break;
942
 
943
	case CMD_PREFIX:
944
 
945
		acpi_db_set_scope(acpi_gbl_db_args[1]);
946
		break;
947
 
948
	case CMD_REFERENCES:
949
 
950
		acpi_db_find_references(acpi_gbl_db_args[1]);
951
		break;
952
 
953
	case CMD_RESOURCES:
954
 
955
		acpi_db_display_resources(acpi_gbl_db_args[1]);
956
		break;
957
 
958
	case CMD_RESULTS:
959
 
960
		acpi_db_display_results();
961
		break;
962
 
963
	case CMD_SET:
964
 
965
		acpi_db_set_method_data(acpi_gbl_db_args[1],
966
					acpi_gbl_db_args[2],
967
					acpi_gbl_db_args[3]);
968
		break;
969
 
970
	case CMD_STATS:
971
 
972
		status = acpi_db_display_statistics(acpi_gbl_db_args[1]);
973
		break;
974
 
975
	case CMD_STOP:
976
 
977
		return (AE_NOT_IMPLEMENTED);
978
 
979
	case CMD_TABLES:
980
 
981
		acpi_db_display_table_info(acpi_gbl_db_args[1]);
982
		break;
983
 
984
	case CMD_TEMPLATE:
985
 
986
		acpi_db_display_template(acpi_gbl_db_args[1]);
987
		break;
988
 
989
	case CMD_TRACE:
990
 
991
		acpi_db_trace(acpi_gbl_db_args[1], acpi_gbl_db_args[2],
992
			      acpi_gbl_db_args[3]);
993
		break;
994
 
995
	case CMD_TREE:
996
 
997
		acpi_db_display_calling_tree();
998
		break;
999
 
1000
	case CMD_TYPE:
1001
 
1002
		acpi_db_display_object_type(acpi_gbl_db_args[1]);
1003
		break;
1004
 
1005
#ifdef ACPI_APPLICATION
1006
 
1007
		/* Hardware simulation commands. */
1008
 
1009
	case CMD_ENABLEACPI:
1010
#if (!ACPI_REDUCED_HARDWARE)
1011
 
1012
		status = acpi_enable();
1013
		if (ACPI_FAILURE(status)) {
1014
			acpi_os_printf("AcpiEnable failed (Status=%X)\n",
1015
				       status);
1016
			return (status);
1017
		}
1018
#endif				/* !ACPI_REDUCED_HARDWARE */
1019
		break;
1020
 
1021
	case CMD_EVENT:
1022
 
1023
		acpi_os_printf("Event command not implemented\n");
1024
		break;
1025
 
1026
	case CMD_GPE:
1027
 
1028
		acpi_db_generate_gpe(acpi_gbl_db_args[1], acpi_gbl_db_args[2]);
1029
		break;
1030
 
1031
	case CMD_GPES:
1032
 
1033
		acpi_db_display_gpes();
1034
		break;
1035
 
1036
	case CMD_SCI:
1037
 
1038
		acpi_db_generate_sci();
1039
		break;
1040
 
1041
	case CMD_SLEEP:
1042
 
1043
		status = acpi_db_sleep(acpi_gbl_db_args[1]);
1044
		break;
1045
 
1046
		/* File I/O commands. */
1047
 
1048
	case CMD_CLOSE:
1049
 
1050
		acpi_db_close_debug_file();
1051
		break;
1052
 
1053
	case CMD_LOAD:
1054
 
1055
		status =
1056
		    acpi_db_get_table_from_file(acpi_gbl_db_args[1], NULL,
1057
						FALSE);
1058
		break;
1059
 
1060
	case CMD_OPEN:
1061
 
1062
		acpi_db_open_debug_file(acpi_gbl_db_args[1]);
1063
		break;
1064
 
1065
		/* User space commands. */
1066
 
1067
	case CMD_TERMINATE:
1068
 
1069
		acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
1070
		acpi_ut_subsystem_shutdown();
1071
 
1072
		/*
1073
		 * TBD: [Restructure] Need some way to re-initialize without
1074
		 * re-creating the semaphores!
1075
		 */
1076
 
1077
		acpi_gbl_db_terminate_loop = TRUE;
1078
		/*  acpi_initialize (NULL); */
1079
		break;
1080
 
1081
	case CMD_THREADS:
1082
 
1083
		acpi_db_create_execution_threads(acpi_gbl_db_args[1],
1084
						 acpi_gbl_db_args[2],
1085
						 acpi_gbl_db_args[3]);
1086
		break;
1087
 
1088
		/* Debug test commands. */
1089
 
1090
	case CMD_PREDEFINED:
1091
 
1092
		acpi_db_check_predefined_names();
1093
		break;
1094
 
1095
	case CMD_TEST:
1096
 
1097
		acpi_db_execute_test(acpi_gbl_db_args[1]);
1098
		break;
1099
 
1100
	case CMD_UNLOAD:
1101
 
1102
		acpi_db_unload_acpi_table(acpi_gbl_db_args[1]);
1103
		break;
1104
#endif
1105
 
1106
	case CMD_EXIT:
1107
	case CMD_QUIT:
1108
 
1109
		if (op) {
1110
			acpi_os_printf("Method execution terminated\n");
1111
			return (AE_CTRL_TERMINATE);
1112
		}
1113
 
1114
		if (!acpi_gbl_db_output_to_file) {
1115
			acpi_dbg_level = ACPI_DEBUG_DEFAULT;
1116
		}
1117
#ifdef ACPI_APPLICATION
1118
		acpi_db_close_debug_file();
1119
#endif
1120
		acpi_gbl_db_terminate_loop = TRUE;
1121
		return (AE_CTRL_TERMINATE);
1122
 
1123
	case CMD_NOT_FOUND:
1124
	default:
1125
 
1126
		acpi_os_printf("%s: unknown command\n", acpi_gbl_db_args[0]);
1127
		return (AE_CTRL_TRUE);
1128
	}
1129
 
1130
	if (ACPI_SUCCESS(status)) {
1131
		status = AE_CTRL_TRUE;
1132
	}
1133
 
1134
	return (status);
1135
}
1136
 
1137
/*******************************************************************************
1138
 *
1139
 * FUNCTION:    acpi_db_execute_thread
1140
 *
1141
 * PARAMETERS:  context         - Not used
1142
 *
1143
 * RETURN:      None
1144
 *
1145
 * DESCRIPTION: Debugger execute thread. Waits for a command line, then
1146
 *              simply dispatches it.
1147
 *
1148
 ******************************************************************************/
1149
 
1150
void ACPI_SYSTEM_XFACE acpi_db_execute_thread(void *context)
1151
{
1152
	acpi_status status = AE_OK;
1153
	acpi_status Mstatus;
1154
 
1155
	while (status != AE_CTRL_TERMINATE && !acpi_gbl_db_terminate_loop) {
1156
		acpi_gbl_method_executing = FALSE;
1157
		acpi_gbl_step_to_next_call = FALSE;
1158
 
1159
		Mstatus = acpi_os_acquire_mutex(acpi_gbl_db_command_ready,
1160
						ACPI_WAIT_FOREVER);
1161
		if (ACPI_FAILURE(Mstatus)) {
1162
			return;
1163
		}
1164
 
1165
		status =
1166
		    acpi_db_command_dispatch(acpi_gbl_db_line_buf, NULL, NULL);
1167
 
1168
		acpi_os_release_mutex(acpi_gbl_db_command_complete);
1169
	}
1170
	acpi_gbl_db_threads_terminated = TRUE;
1171
}
1172
 
1173
/*******************************************************************************
1174
 *
1175
 * FUNCTION:    acpi_db_single_thread
1176
 *
1177
 * PARAMETERS:  None
1178
 *
1179
 * RETURN:      None
1180
 *
1181
 * DESCRIPTION: Debugger execute thread. Waits for a command line, then
1182
 *              simply dispatches it.
1183
 *
1184
 ******************************************************************************/
1185
 
1186
static void acpi_db_single_thread(void)
1187
{
1188
 
1189
	acpi_gbl_method_executing = FALSE;
1190
	acpi_gbl_step_to_next_call = FALSE;
1191
 
1192
	(void)acpi_db_command_dispatch(acpi_gbl_db_line_buf, NULL, NULL);
1193
}
1194
 
1195
/*******************************************************************************
1196
 *
1197
 * FUNCTION:    acpi_db_user_commands
1198
 *
1199
 * PARAMETERS:  prompt              - User prompt (depends on mode)
1200
 *              op                  - Current executing parse op
1201
 *
1202
 * RETURN:      None
1203
 *
1204
 * DESCRIPTION: Command line execution for the AML debugger. Commands are
1205
 *              matched and dispatched here.
1206
 *
1207
 ******************************************************************************/
1208
 
1209
acpi_status acpi_db_user_commands(char prompt, union acpi_parse_object *op)
1210
{
1211
	acpi_status status = AE_OK;
1212
 
1213
	acpi_os_printf("\n");
1214
 
1215
	/* TBD: [Restructure] Need a separate command line buffer for step mode */
1216
 
1217
	while (!acpi_gbl_db_terminate_loop) {
1218
 
1219
		/* Force output to console until a command is entered */
1220
 
1221
		acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
1222
 
1223
		/* Different prompt if method is executing */
1224
 
1225
		if (!acpi_gbl_method_executing) {
1226
			acpi_os_printf("%1c ", ACPI_DEBUGGER_COMMAND_PROMPT);
1227
		} else {
1228
			acpi_os_printf("%1c ", ACPI_DEBUGGER_EXECUTE_PROMPT);
1229
		}
1230
 
1231
		/* Get the user input line */
1232
 
1233
		status = acpi_os_get_line(acpi_gbl_db_line_buf,
1234
					  ACPI_DB_LINE_BUFFER_SIZE, NULL);
1235
		if (ACPI_FAILURE(status)) {
1236
			ACPI_EXCEPTION((AE_INFO, status,
1237
					"While parsing command line"));
1238
			return (status);
1239
		}
1240
 
1241
		/* Check for single or multithreaded debug */
1242
 
1243
		if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED) {
1244
			/*
1245
			 * Signal the debug thread that we have a command to execute,
1246
			 * and wait for the command to complete.
1247
			 */
1248
			acpi_os_release_mutex(acpi_gbl_db_command_ready);
1249
			if (ACPI_FAILURE(status)) {
1250
				return (status);
1251
			}
1252
 
1253
			status =
1254
			    acpi_os_acquire_mutex(acpi_gbl_db_command_complete,
1255
						  ACPI_WAIT_FOREVER);
1256
			if (ACPI_FAILURE(status)) {
1257
				return (status);
1258
			}
1259
		} else {
1260
			/* Just call to the command line interpreter */
1261
 
1262
			acpi_db_single_thread();
1263
		}
1264
	}
1265
 
1266
	return (status);
1267
}