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 | {" |
||
149 | {" |
||
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 | |
||
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 |
||
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, " ! |
||
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 |
||
255 | {1, " Find |
||
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 |
||
262 | {1, " Objects [ObjectType]", |
||
263 | "Display summary of all objects or just given type\n"}, |
||
264 | {1, " Owner |
||
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 [ |
||
269 | {1, " References |
||
270 | {1, " Resources [DeviceName]", |
||
271 | "Display Device resources (no arg = all devices)\n"}, |
||
272 | {1, " Set N |
||
273 | {1, " Template |
||
274 | {1, " Type |
||
275 | |||
276 | {0, "\nControl Method Execution Commands:", "\n"}, |
||
277 | {1, " Arguments (or Args)", "Display method arguments\n"}, |
||
278 | {1, " Breakpoint |
||
279 | {1, " Call", "Run to next control method invocation\n"}, |
||
280 | {1, " Debug |
||
281 | {6, " Evaluate", "Synonym for Execute\n"}, |
||
282 | {5, " Execute |
||
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 <#> |
||
294 | {1, " Stop", "Terminate control method\n"}, |
||
295 | {5, " Trace |
||
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, " |
||
303 | |||
304 | #ifdef ACPI_APPLICATION |
||
305 | {0, "\nHardware Simulation Commands:", "\n"}, |
||
306 | {1, " EnableAcpi", "Enable ACPI (hardware) mode\n"}, |
||
307 | {1, " Event |
||
308 | {1, " Gpe |
||
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 |
||
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 |
||
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 | }>>#> |