term_printf("\n");
}
+typedef struct {
+ int keycode;
+ const char *name;
+} KeyDef;
+
+static const KeyDef key_defs[] = {
+ { 0x2a, "shift" },
+ { 0x36, "shift_r" },
+
+ { 0x38, "alt" },
+ { 0xb8, "alt_r" },
+ { 0x1d, "ctrl" },
+ { 0x9d, "ctrl_r" },
+
+ { 0xdd, "menu" },
+
+ { 0x01, "esc" },
+
+ { 0x02, "1" },
+ { 0x03, "2" },
+ { 0x04, "3" },
+ { 0x05, "4" },
+ { 0x06, "5" },
+ { 0x07, "6" },
+ { 0x08, "7" },
+ { 0x09, "8" },
+ { 0x0a, "9" },
+ { 0x0b, "0" },
+ { 0x0e, "backspace" },
+
+ { 0x0f, "tab" },
+ { 0x10, "q" },
+ { 0x11, "w" },
+ { 0x12, "e" },
+ { 0x13, "r" },
+ { 0x14, "t" },
+ { 0x15, "y" },
+ { 0x16, "u" },
+ { 0x17, "i" },
+ { 0x18, "o" },
+ { 0x19, "p" },
+
+ { 0x1c, "ret" },
+
+ { 0x1e, "a" },
+ { 0x1f, "s" },
+ { 0x20, "d" },
+ { 0x21, "f" },
+ { 0x22, "g" },
+ { 0x23, "h" },
+ { 0x24, "j" },
+ { 0x25, "k" },
+ { 0x26, "l" },
+
+ { 0x2c, "z" },
+ { 0x2d, "x" },
+ { 0x2e, "c" },
+ { 0x2f, "v" },
+ { 0x30, "b" },
+ { 0x31, "n" },
+ { 0x32, "m" },
+
+ { 0x39, "spc" },
+ { 0x3a, "caps_lock" },
+ { 0x3b, "f1" },
+ { 0x3c, "f2" },
+ { 0x3d, "f3" },
+ { 0x3e, "f4" },
+ { 0x3f, "f5" },
+ { 0x40, "f6" },
+ { 0x41, "f7" },
+ { 0x42, "f8" },
+ { 0x43, "f9" },
+ { 0x44, "f10" },
+ { 0x45, "num_lock" },
+ { 0x46, "scroll_lock" },
+
+ { 0x56, "<" },
+
+ { 0x57, "f11" },
+ { 0x58, "f12" },
+
+ { 0xb7, "print" },
+
+ { 0xc7, "home" },
+ { 0xc9, "pgup" },
+ { 0xd1, "pgdn" },
+ { 0xcf, "end" },
+
+ { 0xcb, "left" },
+ { 0xc8, "up" },
+ { 0xd0, "down" },
+ { 0xcd, "right" },
+
+ { 0xd2, "insert" },
+ { 0xd3, "delete" },
+ { 0, NULL },
+};
+
+static int get_keycode(const char *key)
+{
+ const KeyDef *p;
+
+ for(p = key_defs; p->name != NULL; p++) {
+ if (!strcmp(key, p->name))
+ return p->keycode;
+ }
+ return -1;
+}
+
+static void do_send_key(const char *string)
+{
+ char keybuf[16], *q;
+ uint8_t keycodes[16];
+ const char *p;
+ int nb_keycodes, keycode, i;
+
+ nb_keycodes = 0;
+ p = string;
+ while (*p != '\0') {
+ q = keybuf;
+ while (*p != '\0' && *p != '-') {
+ if ((q - keybuf) < sizeof(keybuf) - 1) {
+ *q++ = *p;
+ }
+ p++;
+ }
+ *q = '\0';
+ keycode = get_keycode(keybuf);
+ if (keycode < 0) {
+ term_printf("unknown key: '%s'\n", keybuf);
+ return;
+ }
+ keycodes[nb_keycodes++] = keycode;
+ if (*p == '\0')
+ break;
+ p++;
+ }
+ /* key down events */
+ for(i = 0; i < nb_keycodes; i++) {
+ keycode = keycodes[i];
+ if (keycode & 0x80)
+ kbd_put_keycode(0xe0);
+ kbd_put_keycode(keycode & 0x7f);
+ }
+ /* key up events */
+ for(i = nb_keycodes - 1; i >= 0; i--) {
+ keycode = keycodes[i];
+ if (keycode & 0x80)
+ kbd_put_keycode(0xe0);
+ kbd_put_keycode(keycode | 0x80);
+ }
+}
+
+static void do_ioport_read(int count, int format, int size, int addr, int has_index, int index)
+{
+ uint32_t val;
+ int suffix;
+
+ if (has_index) {
+ cpu_outb(NULL, addr & 0xffff, index & 0xff);
+ addr++;
+ }
+ addr &= 0xffff;
+
+ switch(size) {
+ default:
+ case 1:
+ val = cpu_inb(NULL, addr);
+ suffix = 'b';
+ break;
+ case 2:
+ val = cpu_inw(NULL, addr);
+ suffix = 'w';
+ break;
+ case 4:
+ val = cpu_inl(NULL, addr);
+ suffix = 'l';
+ break;
+ }
+ term_printf("port%c[0x%04x] = %#0*x\n",
+ suffix, addr, size * 2, val);
+}
+
+static void do_system_reset(void)
+{
+ qemu_system_reset_request();
+}
+
static term_cmd_t term_cmds[] = {
{ "help|?", "s?", do_help,
"[cmd]", "show the help" },
"/fmt addr", "physical memory dump starting at 'addr'", },
{ "p|print", "/i", do_print,
"/fmt expr", "print expression value (use $reg for CPU register access)", },
+ { "i", "/ii.", do_ioport_read,
+ "/fmt addr", "I/O port read" },
+
+ { "sendkey", "s", do_send_key,
+ "keys", "send keys to the VM (e.g. 'sendkey ctrl-alt-f1')" },
+ { "system_reset", "", do_system_reset,
+ "", "reset the system" },
{ NULL, NULL, },
};
int val;
while (isspace(*p))
p++;
- if (*typestr == '?') {
+ if (*typestr == '?' || *typestr == '.') {
typestr++;
- if (*p == '\0')
- has_arg = 0;
- else
- has_arg = 1;
+ if (*typestr == '?') {
+ if (*p == '\0')
+ has_arg = 0;
+ else
+ has_arg = 1;
+ } else {
+ if (*p == '.') {
+ p++;
+ while (isspace(*p))
+ p++;
+ has_arg = 1;
+ } else {
+ has_arg = 0;
+ }
+ }
if (nb_args >= MAX_ARGS)
goto error_args;
args[nb_args++] = (void *)has_arg;
case 5:
cmd->handler(args[0], args[1], args[2], args[3], args[4]);
break;
+ case 6:
+ cmd->handler(args[0], args[1], args[2], args[3], args[4], args[5]);
+ break;
default:
term_printf("unsupported number of arguments: %d\n", nb_args);
goto fail;
static void term_print_cmdline (const char *cmdline)
{
term_show_prompt();
- term_printf(cmdline);
+ term_printf("%s", cmdline);
term_flush();
}
}
term_hist_entry--;
if (term_hist_entry >= 0) {
- strcpy(term_cmd_buf, term_history[term_hist_entry]);
+ pstrcpy(term_cmd_buf, sizeof(term_cmd_buf),
+ term_history[term_hist_entry]);
term_printf("\n");
term_print_cmdline(term_cmd_buf);
term_cmd_buf_index = term_cmd_buf_size = strlen(term_cmd_buf);
if (term_hist_entry == TERM_MAX_CMDS - 1 || term_hist_entry == -1)
return;
if (term_history[++term_hist_entry] != NULL) {
- strcpy(term_cmd_buf, term_history[term_hist_entry]);
+ pstrcpy(term_cmd_buf, sizeof(term_cmd_buf),
+ term_history[term_hist_entry]);
} else {
term_hist_entry = -1;
}