1/* $NetBSD$ */ 2 3/*- 4 * Copyright (c) 1999 Takanori Watanabe 5 * Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * Id: debug.c,v 1.19 2000/08/16 18:15:00 iwasaki Exp 30 * $FreeBSD: src/usr.sbin/acpi/amldb/debug.c,v 1.3 2000/11/09 06:24:40 iwasaki Exp $ 31 */ 32#include <sys/cdefs.h> 33__RCSID("$NetBSD$"); 34 35#include <sys/param.h> 36 37#include <acpi_common.h> 38#include <aml/aml_name.h> 39#include <aml/aml_amlmem.h> 40#include <aml/aml_status.h> 41#include <aml/aml_env.h> 42#include <aml/aml_obj.h> 43#include <aml/aml_evalobj.h> 44#include <aml/aml_parse.h> 45#include <aml/aml_region.h> 46#include <aml/aml_store.h> 47#include <aml/aml_common.h> 48 49#include <assert.h> 50#include <err.h> 51#include <stdio.h> 52#include <stdlib.h> 53#include <string.h> 54#include <unistd.h> 55 56#include "debug.h" 57 58static int 59print_named_object(struct aml_name *name, va_list ap) 60{ 61 62 aml_print_curname(name); 63 printf("\n"); 64 65 return (0); /* always return success to continue the search */ 66} 67 68void 69aml_dbgr(struct aml_environ *env1, struct aml_environ *env2) 70{ 71#define CMDBUFLEN 512 72#define ARGBUFLEN 512 73 static char lastcommand[CMDBUFLEN]; 74 char commandline[CMDBUFLEN]; 75 char argbuf[7][ARGBUFLEN]; 76 char *ptr, *method; 77 char *np, *ep; 78 int i; 79 int argnum; 80 struct aml_name *name; 81 union aml_object argv[7], *retval; 82 83 while (1) { 84 fputs("AML>", stderr); 85 fgets(commandline, 512, stdin); 86 commandline[512 - 1] = '\n'; /* safety */ 87 if (feof(stdin)) { 88 commandline[0] = 'q'; 89 } 90 if (commandline[0] == '\n') { 91 memcpy(commandline, lastcommand, sizeof commandline); 92 } 93 memcpy(lastcommand, commandline, sizeof commandline); 94 switch (commandline[0]) { 95 case 's': 96 if (env2 != NULL) { 97 env2->stat = aml_stat_step; 98 } 99 /* FALLTHROUGH */ 100 case 'n': 101 env1->stat = aml_stat_step; 102 return; 103 case 'c': 104 env1->stat = aml_stat_none; 105 return; 106 case 'q': 107 env1->stat = aml_stat_panic; 108 return; 109 case 't': 110 /* NULL terminate */ 111 ptr = &commandline[1]; 112 while (ptr[0] != '\n') 113 ptr++; 114 ptr[0] = '\0'; 115 116 /* move pointer to object name */ 117 ptr = &commandline[1]; 118 while (ptr[0] == ' ') 119 ptr++; 120 121 /* show current tree if no argument */ 122 if (ptr[0] == '\0') { 123 aml_showtree(env1->curname, 0); 124 goto show_variables; 125 } 126 /* start from root? */ 127 if (ptr[0] == '\\') { 128 if (ptr[1] == '\0') { 129 aml_showtree(aml_get_rootname(), 0); 130 goto show_variables; 131 } 132 if ((name = aml_find_from_namespace(aml_get_rootname(), ptr))) { 133 aml_showtree(name, 0); 134 goto show_variables; 135 } 136 } 137 if ((name = aml_find_from_namespace(env1->curname, ptr))) { 138 aml_showtree(name, 0); 139 } 140show_variables: 141 for (i = 0; i < 7; i++) { 142 struct aml_name *tmp = 143 aml_local_stack_getArgX(NULL, i); 144 145 if (tmp == NULL || tmp->property == NULL) { 146 break; 147 } 148 printf(" Arg%d ", i); 149 aml_showobject(tmp->property); 150 } 151 for (i = 0; i < 8; i++) { 152 struct aml_name *tmp = 153 aml_local_stack_getLocalX(i); 154 155 if (tmp == NULL || tmp->property == NULL) { 156 continue; 157 } 158 printf(" Local%d ", i); 159 aml_showobject(tmp->property); 160 } 161 break; 162 case 'i': 163 aml_debug_prompt_reginput = 164 (aml_debug_prompt_reginput == 0) ? 1 : 0; 165 if (aml_debug_prompt_reginput) 166 fputs("REGION INPUT ON\n", stderr); 167 else 168 fputs("REGION INPUT OFF\n", stderr); 169 break; 170 case 'o': 171 aml_debug_prompt_regoutput = 172 (aml_debug_prompt_regoutput == 0) ? 1 : 0; 173 if (aml_debug_prompt_regoutput) 174 fputs("REGION OUTPUT ON\n", stderr); 175 else 176 fputs("REGION OUTPUT OFF\n", stderr); 177 break; 178 case 'm': 179 memman_statistics(aml_memman); 180 break; 181 case 'r': 182 /* NULL terminate */ 183 ptr = &commandline[1]; 184 while (ptr[0] != '\n') 185 ptr++; 186 ptr[0] = '\0'; 187 188 /* move pointer to method name */ 189 ptr = &commandline[1]; 190 while (ptr[0] == ' ') 191 ptr++; 192 193 if (ptr[0] == '\0') { 194 break; 195 } 196 name = aml_find_from_namespace(aml_get_rootname(), ptr); 197 if (name == NULL) { 198 printf("%s:%d:aml_dbgr: not found name %s\n", 199 __FILE__, __LINE__, ptr); 200 break; 201 } 202 if (name->property == NULL || 203 name->property->type != aml_t_method) { 204 printf("%s:%d:aml_dbgr: not method %s\n", 205 __FILE__, __LINE__, ptr); 206 break; 207 } 208 aml_showobject(name->property); 209 method = ptr; 210 211 argnum = name->property->meth.argnum & 0x07; 212 if (argnum) { 213 fputs(" Enter argument values " 214 "(ex. number 1 / string foo). " 215 "'q' to quit.\n", stderr); 216 } 217 /* get and parse argument values */ 218 for (i = 0; i < argnum; i++) { 219retry: 220 fprintf(stderr, " Arg%d ? ", i); 221 if (read(0, argbuf[i], ARGBUFLEN) == 0) { 222 fputs("\n", stderr); 223 goto retry; 224 } 225 argbuf[i][ARGBUFLEN - 1] = '\n'; 226 if (argbuf[i][0] == 'q') { 227 goto finish_execution; 228 } 229 if (argbuf[i][0] == '\n') { 230 goto retry; 231 } 232 /* move pointer to the value */ 233 ptr = &argbuf[i][0]; 234 while (ptr[0] != ' ' && ptr[0] != '\n') { 235 ptr++; 236 } 237 while (ptr[0] == ' ') { 238 ptr++; 239 } 240 if (ptr[0] == '\n') { 241 goto retry; 242 } 243 switch (argbuf[i][0]) { 244 case 'n': 245 argv[i].type = aml_t_num; 246 np = ptr; 247 if (ptr[0] == '0' && 248 ptr[1] == 'x') { 249 argv[i].num.number = strtoq(ptr, &ep, 16); 250 } else { 251 argv[i].num.number = strtoq(ptr, &ep, 10); 252 } 253 if (np == ep) { 254 fputs("Wrong value for number.\n", 255 stderr); 256 goto retry; 257 } 258 break; 259 case 's': 260 argv[i].type = aml_t_string; 261 argv[i].str.needfree = 0; 262 argv[i].str.string = (u_int8_t *)ptr; 263 /* NULL ternimate */ 264 while (ptr[0] != '\n') { 265 ptr++; 266 } 267 ptr[0] = '\0'; 268 break; 269 default: 270 fputs("Invalid data type " 271 "(supports number or string only)\n", 272 stderr); 273 goto retry; 274 } 275 } 276 bzero(lastcommand, sizeof lastcommand); 277 fprintf(stderr, "==== Running %s. ====\n", method); 278 aml_local_stack_push(aml_local_stack_create()); 279 retval = aml_invoke_method_by_name(method, argnum, argv); 280 aml_showobject(retval); 281 aml_local_stack_delete(aml_local_stack_pop()); 282 fprintf(stderr, "==== %s finished. ====\n", method); 283finish_execution: 284 break; 285 case 'f': 286 /* NULL terminate */ 287 ptr = &commandline[1]; 288 while (ptr[0] != '\n') 289 ptr++; 290 ptr[0] = '\0'; 291 292 /* move pointer to object name */ 293 ptr = &commandline[1]; 294 while (ptr[0] == ' ') 295 ptr++; 296 297 aml_apply_foreach_found_objects(aml_get_rootname(), 298 ptr, print_named_object); 299 break; 300 case 'h': 301 fputs("s Single step\n" 302 "n Step program\n" 303 "c Continue program being debugged\n" 304 "q Quit method execution\n" 305 "t Show local name space tree and variables\n" 306 "i Toggle region input prompt\n" 307 "o Toggle region output prompt\n" 308 "m Show memory management statistics\n" 309 "r Run specified method\n" 310 "f Find named objects from namespace.\n" 311 "h Show this messsage\n", stderr); 312 break; 313 } 314 } 315} 316