Statistics
| Branch: | Revision:

root / monitor.c @ 3e11db9a

History | View | Annotate | Download (49.8 kB)

1
/*
2
 * QEMU monitor
3
 * 
4
 * Copyright (c) 2003-2004 Fabrice Bellard
5
 * 
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24
#include "vl.h"
25
#include "disas.h"
26
#include <dirent.h>
27

    
28
//#define DEBUG
29
//#define DEBUG_COMPLETION
30

    
31
#ifndef offsetof
32
#define offsetof(type, field) ((size_t) &((type *)0)->field)
33
#endif
34

    
35
#define TERM_CMD_BUF_SIZE 4095
36
#define TERM_MAX_CMDS 64
37
#define NB_COMPLETIONS_MAX 256
38

    
39
#define IS_NORM 0
40
#define IS_ESC  1
41
#define IS_CSI  2
42

    
43
#define printf do_not_use_printf
44

    
45
static char term_cmd_buf[TERM_CMD_BUF_SIZE + 1];
46
static int term_cmd_buf_index;
47
static int term_cmd_buf_size;
48

    
49
static char term_last_cmd_buf[TERM_CMD_BUF_SIZE + 1];
50
static int term_last_cmd_buf_index;
51
static int term_last_cmd_buf_size;
52

    
53
static int term_esc_state;
54
static int term_esc_param;
55

    
56
static char *term_history[TERM_MAX_CMDS];
57
static int term_hist_entry;
58
static CharDriverState *monitor_hd;
59

    
60
static int nb_completions;
61
static int completion_index;
62
static char *completions[NB_COMPLETIONS_MAX];
63

    
64

    
65
/*
66
 * Supported types:
67
 * 
68
 * 'F'          filename
69
 * 'B'          block device name
70
 * 's'          string (accept optional quote)
71
 * 'i'          integer
72
 * '/'          optional gdb-like print format (like "/10x")
73
 *
74
 * '?'          optional type (for 'F', 's' and 'i')
75
 *
76
 */
77

    
78
typedef struct term_cmd_t {
79
    const char *name;
80
    const char *args_type;
81
    void (*handler)();
82
    const char *params;
83
    const char *help;
84
} term_cmd_t;
85

    
86
static term_cmd_t term_cmds[];
87
static term_cmd_t info_cmds[];
88

    
89
static void add_completion(const char *str);
90

    
91
void term_printf(const char *fmt, ...)
92
{
93
    char buf[4096];
94
    va_list ap;
95
    va_start(ap, fmt);
96
    vsnprintf(buf, sizeof(buf), fmt, ap);
97
    qemu_chr_write(monitor_hd, buf, strlen(buf));
98
    va_end(ap);
99
}
100

    
101
void term_flush(void)
102
{
103
}
104

    
105
static int compare_cmd(const char *name, const char *list)
106
{
107
    const char *p, *pstart;
108
    int len;
109
    len = strlen(name);
110
    p = list;
111
    for(;;) {
112
        pstart = p;
113
        p = strchr(p, '|');
114
        if (!p)
115
            p = pstart + strlen(pstart);
116
        if ((p - pstart) == len && !memcmp(pstart, name, len))
117
            return 1;
118
        if (*p == '\0')
119
            break;
120
        p++;
121
    }
122
    return 0;
123
}
124

    
125
static void help_cmd1(term_cmd_t *cmds, const char *prefix, const char *name)
126
{
127
    term_cmd_t *cmd;
128

    
129
    for(cmd = cmds; cmd->name != NULL; cmd++) {
130
        if (!name || !strcmp(name, cmd->name))
131
            term_printf("%s%s %s -- %s\n", prefix, cmd->name, cmd->params, cmd->help);
132
    }
133
}
134

    
135
static void help_cmd(const char *name)
136
{
137
    if (name && !strcmp(name, "info")) {
138
        help_cmd1(info_cmds, "info ", NULL);
139
    } else {
140
        help_cmd1(term_cmds, "", name);
141
        if (name && !strcmp(name, "log")) {
142
            CPULogItem *item;
143
            term_printf("Log items (comma separated):\n");
144
            term_printf("%-10s %s\n", "none", "remove all logs");
145
            for(item = cpu_log_items; item->mask != 0; item++) {
146
                term_printf("%-10s %s\n", item->name, item->help);
147
            }
148
        }
149
    }
150
}
151

    
152
static void do_help(const char *name)
153
{
154
    help_cmd(name);
155
}
156

    
157
static void do_commit(void)
158
{
159
    int i;
160

    
161
    for (i = 0; i < MAX_DISKS; i++) {
162
        if (bs_table[i])
163
            bdrv_commit(bs_table[i]);
164
    }
165
}
166

    
167
static void do_info(const char *item)
168
{
169
    term_cmd_t *cmd;
170

    
171
    if (!item)
172
        goto help;
173
    for(cmd = info_cmds; cmd->name != NULL; cmd++) {
174
        if (compare_cmd(item, cmd->name)) 
175
            goto found;
176
    }
177
 help:
178
    help_cmd("info");
179
    return;
180
 found:
181
    cmd->handler();
182
}
183

    
184
static void do_info_network(void)
185
{
186
    int i, j;
187
    NetDriverState *nd;
188
    
189
    for(i = 0; i < nb_nics; i++) {
190
        nd = &nd_table[i];
191
        term_printf("%d: ifname=%s macaddr=", i, nd->ifname);
192
        for(j = 0; j < 6; j++) {
193
            if (j > 0)
194
                term_printf(":");
195
            term_printf("%02x", nd->macaddr[j]);
196
        }
197
        term_printf("\n");
198
    }
199
}
200
 
201
static void do_info_block(void)
202
{
203
    bdrv_info();
204
}
205

    
206
static void do_info_registers(void)
207
{
208
#ifdef TARGET_I386
209
    cpu_dump_state(cpu_single_env, stdout, X86_DUMP_FPU | X86_DUMP_CCOP);
210
#else
211
    cpu_dump_state(cpu_single_env, stdout, 0);
212
#endif
213
}
214

    
215
static void do_info_history (void)
216
{
217
    int i;
218

    
219
    for (i = 0; i < TERM_MAX_CMDS; i++) {
220
        if (term_history[i] == NULL)
221
            break;
222
        term_printf("%d: '%s'\n", i, term_history[i]);
223
    }
224
}
225

    
226
static void do_quit(void)
227
{
228
    exit(0);
229
}
230

    
231
static int eject_device(BlockDriverState *bs, int force)
232
{
233
    if (bdrv_is_inserted(bs)) {
234
        if (!force) {
235
            if (!bdrv_is_removable(bs)) {
236
                term_printf("device is not removable\n");
237
                return -1;
238
            }
239
            if (bdrv_is_locked(bs)) {
240
                term_printf("device is locked\n");
241
                return -1;
242
            }
243
        }
244
        bdrv_close(bs);
245
    }
246
    return 0;
247
}
248

    
249
static void do_eject(int force, const char *filename)
250
{
251
    BlockDriverState *bs;
252

    
253
    bs = bdrv_find(filename);
254
    if (!bs) {
255
        term_printf("device not found\n");
256
        return;
257
    }
258
    eject_device(bs, force);
259
}
260

    
261
static void do_change(const char *device, const char *filename)
262
{
263
    BlockDriverState *bs;
264

    
265
    bs = bdrv_find(device);
266
    if (!bs) {
267
        term_printf("device not found\n");
268
        return;
269
    }
270
    if (eject_device(bs, 0) < 0)
271
        return;
272
    bdrv_open(bs, filename, 0);
273
}
274

    
275
static void do_screen_dump(const char *filename)
276
{
277
    vga_screen_dump(filename);
278
}
279

    
280
static void do_log(const char *items)
281
{
282
    int mask;
283
    
284
    if (!strcmp(items, "none")) {
285
        mask = 0;
286
    } else {
287
        mask = cpu_str_to_log_mask(items);
288
        if (!mask) {
289
            help_cmd("log");
290
            return;
291
        }
292
    }
293
    cpu_set_log(mask);
294
}
295

    
296
static void do_savevm(const char *filename)
297
{
298
    if (qemu_savevm(filename) < 0)
299
        term_printf("I/O error when saving VM to '%s'\n", filename);
300
}
301

    
302
static void do_loadvm(const char *filename)
303
{
304
    if (qemu_loadvm(filename) < 0) 
305
        term_printf("I/O error when loading VM from '%s'\n", filename);
306
}
307

    
308
static void do_stop(void)
309
{
310
    vm_stop(EXCP_INTERRUPT);
311
}
312

    
313
static void do_cont(void)
314
{
315
    vm_start();
316
}
317

    
318
#ifdef CONFIG_GDBSTUB
319
static void do_gdbserver(int has_port, int port)
320
{
321
    if (!has_port)
322
        port = DEFAULT_GDBSTUB_PORT;
323
    if (gdbserver_start(port) < 0) {
324
        qemu_printf("Could not open gdbserver socket on port %d\n", port);
325
    } else {
326
        qemu_printf("Waiting gdb connection on port %d\n", port);
327
    }
328
}
329
#endif
330

    
331
static void term_printc(int c)
332
{
333
    term_printf("'");
334
    switch(c) {
335
    case '\'':
336
        term_printf("\\'");
337
        break;
338
    case '\\':
339
        term_printf("\\\\");
340
        break;
341
    case '\n':
342
        term_printf("\\n");
343
        break;
344
    case '\r':
345
        term_printf("\\r");
346
        break;
347
    default:
348
        if (c >= 32 && c <= 126) {
349
            term_printf("%c", c);
350
        } else {
351
            term_printf("\\x%02x", c);
352
        }
353
        break;
354
    }
355
    term_printf("'");
356
}
357

    
358
static void memory_dump(int count, int format, int wsize, 
359
                        target_ulong addr, int is_physical)
360
{
361
    int nb_per_line, l, line_size, i, max_digits, len;
362
    uint8_t buf[16];
363
    uint64_t v;
364

    
365
    if (format == 'i') {
366
        int flags;
367
        flags = 0;
368
#ifdef TARGET_I386
369
        if (wsize == 2) {
370
            flags = 1;
371
        } else if (wsize == 4) {
372
            flags = 0;
373
        } else {
374
            /* as default we use the current CS size */
375
            flags = 0;
376
            if (!(cpu_single_env->segs[R_CS].flags & DESC_B_MASK))
377
                flags = 1;
378
        }
379
#endif
380
        monitor_disas(addr, count, is_physical, flags);
381
        return;
382
    }
383

    
384
    len = wsize * count;
385
    if (wsize == 1)
386
        line_size = 8;
387
    else
388
        line_size = 16;
389
    nb_per_line = line_size / wsize;
390
    max_digits = 0;
391

    
392
    switch(format) {
393
    case 'o':
394
        max_digits = (wsize * 8 + 2) / 3;
395
        break;
396
    default:
397
    case 'x':
398
        max_digits = (wsize * 8) / 4;
399
        break;
400
    case 'u':
401
    case 'd':
402
        max_digits = (wsize * 8 * 10 + 32) / 33;
403
        break;
404
    case 'c':
405
        wsize = 1;
406
        break;
407
    }
408

    
409
    while (len > 0) {
410
        term_printf("0x%08x:", addr);
411
        l = len;
412
        if (l > line_size)
413
            l = line_size;
414
        if (is_physical) {
415
            cpu_physical_memory_rw(addr, buf, l, 0);
416
        } else {
417
            cpu_memory_rw_debug(cpu_single_env, addr, buf, l, 0);
418
        }
419
        i = 0; 
420
        while (i < l) {
421
            switch(wsize) {
422
            default:
423
            case 1:
424
                v = ldub_raw(buf + i);
425
                break;
426
            case 2:
427
                v = lduw_raw(buf + i);
428
                break;
429
            case 4:
430
                v = ldl_raw(buf + i);
431
                break;
432
            case 8:
433
                v = ldq_raw(buf + i);
434
                break;
435
            }
436
            term_printf(" ");
437
            switch(format) {
438
            case 'o':
439
                term_printf("%#*llo", max_digits, v);
440
                break;
441
            case 'x':
442
                term_printf("0x%0*llx", max_digits, v);
443
                break;
444
            case 'u':
445
                term_printf("%*llu", max_digits, v);
446
                break;
447
            case 'd':
448
                term_printf("%*lld", max_digits, v);
449
                break;
450
            case 'c':
451
                term_printc(v);
452
                break;
453
            }
454
            i += wsize;
455
        }
456
        term_printf("\n");
457
        addr += l;
458
        len -= l;
459
    }
460
}
461

    
462
static void do_memory_dump(int count, int format, int size, int addr)
463
{
464
    memory_dump(count, format, size, addr, 0);
465
}
466

    
467
static void do_physical_memory_dump(int count, int format, int size, int addr)
468
{
469
    memory_dump(count, format, size, addr, 1);
470
}
471

    
472
static void do_print(int count, int format, int size, int val)
473
{
474
    switch(format) {
475
    case 'o':
476
        term_printf("%#o", val);
477
        break;
478
    case 'x':
479
        term_printf("%#x", val);
480
        break;
481
    case 'u':
482
        term_printf("%u", val);
483
        break;
484
    default:
485
    case 'd':
486
        term_printf("%d", val);
487
        break;
488
    case 'c':
489
        term_printc(val);
490
        break;
491
    }
492
    term_printf("\n");
493
}
494

    
495
typedef struct {
496
    int keycode;
497
    const char *name;
498
} KeyDef;
499

    
500
static const KeyDef key_defs[] = {
501
    { 0x2a, "shift" },
502
    { 0x36, "shift_r" },
503
    
504
    { 0x38, "alt" },
505
    { 0xb8, "alt_r" },
506
    { 0x1d, "ctrl" },
507
    { 0x9d, "ctrl_r" },
508

    
509
    { 0xdd, "menu" },
510

    
511
    { 0x01, "esc" },
512

    
513
    { 0x02, "1" },
514
    { 0x03, "2" },
515
    { 0x04, "3" },
516
    { 0x05, "4" },
517
    { 0x06, "5" },
518
    { 0x07, "6" },
519
    { 0x08, "7" },
520
    { 0x09, "8" },
521
    { 0x0a, "9" },
522
    { 0x0b, "0" },
523
    { 0x0e, "backspace" },
524

    
525
    { 0x0f, "tab" },
526
    { 0x10, "q" },
527
    { 0x11, "w" },
528
    { 0x12, "e" },
529
    { 0x13, "r" },
530
    { 0x14, "t" },
531
    { 0x15, "y" },
532
    { 0x16, "u" },
533
    { 0x17, "i" },
534
    { 0x18, "o" },
535
    { 0x19, "p" },
536

    
537
    { 0x1c, "ret" },
538

    
539
    { 0x1e, "a" },
540
    { 0x1f, "s" },
541
    { 0x20, "d" },
542
    { 0x21, "f" },
543
    { 0x22, "g" },
544
    { 0x23, "h" },
545
    { 0x24, "j" },
546
    { 0x25, "k" },
547
    { 0x26, "l" },
548

    
549
    { 0x2c, "z" },
550
    { 0x2d, "x" },
551
    { 0x2e, "c" },
552
    { 0x2f, "v" },
553
    { 0x30, "b" },
554
    { 0x31, "n" },
555
    { 0x32, "m" },
556
    
557
    { 0x39, "spc" },
558
    { 0x3a, "caps_lock" },
559
    { 0x3b, "f1" },
560
    { 0x3c, "f2" },
561
    { 0x3d, "f3" },
562
    { 0x3e, "f4" },
563
    { 0x3f, "f5" },
564
    { 0x40, "f6" },
565
    { 0x41, "f7" },
566
    { 0x42, "f8" },
567
    { 0x43, "f9" },
568
    { 0x44, "f10" },
569
    { 0x45, "num_lock" },
570
    { 0x46, "scroll_lock" },
571

    
572
    { 0x56, "<" },
573

    
574
    { 0x57, "f11" },
575
    { 0x58, "f12" },
576

    
577
    { 0xb7, "print" },
578

    
579
    { 0xc7, "home" },
580
    { 0xc9, "pgup" },
581
    { 0xd1, "pgdn" },
582
    { 0xcf, "end" },
583

    
584
    { 0xcb, "left" },
585
    { 0xc8, "up" },
586
    { 0xd0, "down" },
587
    { 0xcd, "right" },
588

    
589
    { 0xd2, "insert" },
590
    { 0xd3, "delete" },
591
    { 0, NULL },
592
};
593

    
594
static int get_keycode(const char *key)
595
{
596
    const KeyDef *p;
597

    
598
    for(p = key_defs; p->name != NULL; p++) {
599
        if (!strcmp(key, p->name))
600
            return p->keycode;
601
    }
602
    return -1;
603
}
604

    
605
static void do_send_key(const char *string)
606
{
607
    char keybuf[16], *q;
608
    uint8_t keycodes[16];
609
    const char *p;
610
    int nb_keycodes, keycode, i;
611
    
612
    nb_keycodes = 0;
613
    p = string;
614
    while (*p != '\0') {
615
        q = keybuf;
616
        while (*p != '\0' && *p != '-') {
617
            if ((q - keybuf) < sizeof(keybuf) - 1) {
618
                *q++ = *p;
619
            }
620
            p++;
621
        }
622
        *q = '\0';
623
        keycode = get_keycode(keybuf);
624
        if (keycode < 0) {
625
            term_printf("unknown key: '%s'\n", keybuf);
626
            return;
627
        }
628
        keycodes[nb_keycodes++] = keycode;
629
        if (*p == '\0')
630
            break;
631
        p++;
632
    }
633
    /* key down events */
634
    for(i = 0; i < nb_keycodes; i++) {
635
        keycode = keycodes[i];
636
        if (keycode & 0x80)
637
            kbd_put_keycode(0xe0);
638
        kbd_put_keycode(keycode & 0x7f);
639
    }
640
    /* key up events */
641
    for(i = nb_keycodes - 1; i >= 0; i--) {
642
        keycode = keycodes[i];
643
        if (keycode & 0x80)
644
            kbd_put_keycode(0xe0);
645
        kbd_put_keycode(keycode | 0x80);
646
    }
647
}
648

    
649
static void do_ioport_read(int count, int format, int size, int addr, int has_index, int index)
650
{
651
    uint32_t val;
652
    int suffix;
653

    
654
    if (has_index) {
655
        cpu_outb(NULL, addr & 0xffff, index & 0xff);
656
        addr++;
657
    }
658
    addr &= 0xffff;
659

    
660
    switch(size) {
661
    default:
662
    case 1:
663
        val = cpu_inb(NULL, addr);
664
        suffix = 'b';
665
        break;
666
    case 2:
667
        val = cpu_inw(NULL, addr);
668
        suffix = 'w';
669
        break;
670
    case 4:
671
        val = cpu_inl(NULL, addr);
672
        suffix = 'l';
673
        break;
674
    }
675
    term_printf("port%c[0x%04x] = %#0*x\n",
676
                suffix, addr, size * 2, val);
677
}
678

    
679
static void do_system_reset(void)
680
{
681
    qemu_system_reset_request();
682
}
683

    
684
static term_cmd_t term_cmds[] = {
685
    { "help|?", "s?", do_help, 
686
      "[cmd]", "show the help" },
687
    { "commit", "", do_commit, 
688
      "", "commit changes to the disk images (if -snapshot is used)" },
689
    { "info", "s?", do_info,
690
      "subcommand", "show various information about the system state" },
691
    { "q|quit", "", do_quit,
692
      "", "quit the emulator" },
693
    { "eject", "-fB", do_eject,
694
      "[-f] device", "eject a removable media (use -f to force it)" },
695
    { "change", "BF", do_change,
696
      "device filename", "change a removable media" },
697
    { "screendump", "F", do_screen_dump, 
698
      "filename", "save screen into PPM image 'filename'" },
699
    { "log", "s", do_log,
700
      "item1[,...]", "activate logging of the specified items to '/tmp/qemu.log'" }, 
701
    { "savevm", "F", do_savevm,
702
      "filename", "save the whole virtual machine state to 'filename'" }, 
703
    { "loadvm", "F", do_loadvm,
704
      "filename", "restore the whole virtual machine state from 'filename'" }, 
705
    { "stop", "", do_stop, 
706
      "", "stop emulation", },
707
    { "c|cont", "", do_cont, 
708
      "", "resume emulation", },
709
#ifdef CONFIG_GDBSTUB
710
    { "gdbserver", "i?", do_gdbserver, 
711
      "[port]", "start gdbserver session (default port=1234)", },
712
#endif
713
    { "x", "/i", do_memory_dump, 
714
      "/fmt addr", "virtual memory dump starting at 'addr'", },
715
    { "xp", "/i", do_physical_memory_dump, 
716
      "/fmt addr", "physical memory dump starting at 'addr'", },
717
    { "p|print", "/i", do_print, 
718
      "/fmt expr", "print expression value (use $reg for CPU register access)", },
719
    { "i", "/ii.", do_ioport_read, 
720
      "/fmt addr", "I/O port read" },
721

    
722
    { "sendkey", "s", do_send_key, 
723
      "keys", "send keys to the VM (e.g. 'sendkey ctrl-alt-f1')" },
724
    { "system_reset", "", do_system_reset, 
725
      "", "reset the system" },
726
    { NULL, NULL, }, 
727
};
728

    
729
static term_cmd_t info_cmds[] = {
730
    { "network", "", do_info_network,
731
      "", "show the network state" },
732
    { "block", "", do_info_block,
733
      "", "show the block devices" },
734
    { "registers", "", do_info_registers,
735
      "", "show the cpu registers" },
736
    { "history", "", do_info_history,
737
      "", "show the command line history", },
738
    { "irq", "", irq_info,
739
      "", "show the interrupts statistics (if available)", },
740
    { "pic", "", pic_info,
741
      "", "show i8259 (PIC) state", },
742
    { "pci", "", pci_info,
743
      "", "show PCI info", },
744
    { NULL, NULL, },
745
};
746

    
747
/*******************************************************************/
748

    
749
static const char *pch;
750
static jmp_buf expr_env;
751

    
752
typedef struct MonitorDef {
753
    const char *name;
754
    int offset;
755
    int (*get_value)(struct MonitorDef *md);
756
} MonitorDef;
757

    
758
#if defined(TARGET_I386)
759
static int monitor_get_pc (struct MonitorDef *md)
760
{
761
    return cpu_single_env->eip + (long)cpu_single_env->segs[R_CS].base;
762
}
763
#endif
764

    
765
#if defined(TARGET_PPC)
766
static int monitor_get_ccr (struct MonitorDef *md)
767
{
768
    unsigned int u;
769
    int i;
770

    
771
    u = 0;
772
    for (i = 0; i < 8; i++)
773
        u |= cpu_single_env->crf[i] << (32 - (4 * i));
774

    
775
    return u;
776
}
777

    
778
static int monitor_get_msr (struct MonitorDef *md)
779
{
780
    return (cpu_single_env->msr[MSR_POW] << MSR_POW) |
781
        (cpu_single_env->msr[MSR_ILE] << MSR_ILE) |
782
        (cpu_single_env->msr[MSR_EE] << MSR_EE) |
783
        (cpu_single_env->msr[MSR_PR] << MSR_PR) |
784
        (cpu_single_env->msr[MSR_FP] << MSR_FP) |
785
        (cpu_single_env->msr[MSR_ME] << MSR_ME) |
786
        (cpu_single_env->msr[MSR_FE0] << MSR_FE0) |
787
        (cpu_single_env->msr[MSR_SE] << MSR_SE) |
788
        (cpu_single_env->msr[MSR_BE] << MSR_BE) |
789
        (cpu_single_env->msr[MSR_FE1] << MSR_FE1) |
790
        (cpu_single_env->msr[MSR_IP] << MSR_IP) |
791
        (cpu_single_env->msr[MSR_IR] << MSR_IR) |
792
        (cpu_single_env->msr[MSR_DR] << MSR_DR) |
793
        (cpu_single_env->msr[MSR_RI] << MSR_RI) |
794
        (cpu_single_env->msr[MSR_LE] << MSR_LE);
795
}
796

    
797
static int monitor_get_xer (struct MonitorDef *md)
798
{
799
    return (cpu_single_env->xer[XER_SO] << XER_SO) |
800
        (cpu_single_env->xer[XER_OV] << XER_OV) |
801
        (cpu_single_env->xer[XER_CA] << XER_CA) |
802
        (cpu_single_env->xer[XER_BC] << XER_BC);
803
}
804

    
805
uint32_t cpu_ppc_load_decr (CPUState *env);
806
static int monitor_get_decr (struct MonitorDef *md)
807
{
808
    return cpu_ppc_load_decr(cpu_single_env);
809
}
810

    
811
uint32_t cpu_ppc_load_tbu (CPUState *env);
812
static int monitor_get_tbu (struct MonitorDef *md)
813
{
814
    return cpu_ppc_load_tbu(cpu_single_env);
815
}
816

    
817
uint32_t cpu_ppc_load_tbl (CPUState *env);
818
static int monitor_get_tbl (struct MonitorDef *md)
819
{
820
    return cpu_ppc_load_tbl(cpu_single_env);
821
}
822
#endif
823

    
824
static MonitorDef monitor_defs[] = {
825
#ifdef TARGET_I386
826

    
827
#define SEG(name, seg) \
828
    { name, offsetof(CPUState, segs[seg].selector) },\
829
    { name ".base", offsetof(CPUState, segs[seg].base) },\
830
    { name ".limit", offsetof(CPUState, segs[seg].limit) },
831

    
832
    { "eax", offsetof(CPUState, regs[0]) },
833
    { "ecx", offsetof(CPUState, regs[1]) },
834
    { "edx", offsetof(CPUState, regs[2]) },
835
    { "ebx", offsetof(CPUState, regs[3]) },
836
    { "esp|sp", offsetof(CPUState, regs[4]) },
837
    { "ebp|fp", offsetof(CPUState, regs[5]) },
838
    { "esi", offsetof(CPUState, regs[6]) },
839
    { "esi", offsetof(CPUState, regs[7]) },
840
    { "eflags", offsetof(CPUState, eflags) },
841
    { "eip", offsetof(CPUState, eip) },
842
    SEG("cs", R_CS)
843
    SEG("ds", R_DS)
844
    SEG("es", R_ES)
845
    SEG("fs", R_FS)
846
    SEG("gs", R_GS)
847
    { "pc", 0, monitor_get_pc, },
848
#elif defined(TARGET_PPC)
849
    { "r0", offsetof(CPUState, gpr[0]) },
850
    { "r1", offsetof(CPUState, gpr[1]) },
851
    { "r2", offsetof(CPUState, gpr[2]) },
852
    { "r3", offsetof(CPUState, gpr[3]) },
853
    { "r4", offsetof(CPUState, gpr[4]) },
854
    { "r5", offsetof(CPUState, gpr[5]) },
855
    { "r6", offsetof(CPUState, gpr[6]) },
856
    { "r7", offsetof(CPUState, gpr[7]) },
857
    { "r8", offsetof(CPUState, gpr[8]) },
858
    { "r9", offsetof(CPUState, gpr[9]) },
859
    { "r10", offsetof(CPUState, gpr[10]) },
860
    { "r11", offsetof(CPUState, gpr[11]) },
861
    { "r12", offsetof(CPUState, gpr[12]) },
862
    { "r13", offsetof(CPUState, gpr[13]) },
863
    { "r14", offsetof(CPUState, gpr[14]) },
864
    { "r15", offsetof(CPUState, gpr[15]) },
865
    { "r16", offsetof(CPUState, gpr[16]) },
866
    { "r17", offsetof(CPUState, gpr[17]) },
867
    { "r18", offsetof(CPUState, gpr[18]) },
868
    { "r19", offsetof(CPUState, gpr[19]) },
869
    { "r20", offsetof(CPUState, gpr[20]) },
870
    { "r21", offsetof(CPUState, gpr[21]) },
871
    { "r22", offsetof(CPUState, gpr[22]) },
872
    { "r23", offsetof(CPUState, gpr[23]) },
873
    { "r24", offsetof(CPUState, gpr[24]) },
874
    { "r25", offsetof(CPUState, gpr[25]) },
875
    { "r26", offsetof(CPUState, gpr[26]) },
876
    { "r27", offsetof(CPUState, gpr[27]) },
877
    { "r28", offsetof(CPUState, gpr[28]) },
878
    { "r29", offsetof(CPUState, gpr[29]) },
879
    { "r30", offsetof(CPUState, gpr[30]) },
880
    { "r31", offsetof(CPUState, gpr[31]) },
881
    { "nip|pc", offsetof(CPUState, nip) },
882
    { "lr", offsetof(CPUState, lr) },
883
    { "ctr", offsetof(CPUState, ctr) },
884
    { "decr", 0, &monitor_get_decr, },
885
    { "ccr", 0, &monitor_get_ccr, },
886
    { "msr", 0, &monitor_get_msr, },
887
    { "xer", 0, &monitor_get_xer, },
888
    { "tbu", 0, &monitor_get_tbu, },
889
    { "tbl", 0, &monitor_get_tbl, },
890
    { "sdr1", offsetof(CPUState, sdr1) },
891
    { "sr0", offsetof(CPUState, sr[0]) },
892
    { "sr1", offsetof(CPUState, sr[1]) },
893
    { "sr2", offsetof(CPUState, sr[2]) },
894
    { "sr3", offsetof(CPUState, sr[3]) },
895
    { "sr4", offsetof(CPUState, sr[4]) },
896
    { "sr5", offsetof(CPUState, sr[5]) },
897
    { "sr6", offsetof(CPUState, sr[6]) },
898
    { "sr7", offsetof(CPUState, sr[7]) },
899
    { "sr8", offsetof(CPUState, sr[8]) },
900
    { "sr9", offsetof(CPUState, sr[9]) },
901
    { "sr10", offsetof(CPUState, sr[10]) },
902
    { "sr11", offsetof(CPUState, sr[11]) },
903
    { "sr12", offsetof(CPUState, sr[12]) },
904
    { "sr13", offsetof(CPUState, sr[13]) },
905
    { "sr14", offsetof(CPUState, sr[14]) },
906
    { "sr15", offsetof(CPUState, sr[15]) },
907
    /* Too lazy to put BATs and SPRs ... */
908
#endif
909
    { NULL },
910
};
911

    
912
static void expr_error(const char *fmt) 
913
{
914
    term_printf(fmt);
915
    term_printf("\n");
916
    longjmp(expr_env, 1);
917
}
918

    
919
static int get_monitor_def(int *pval, const char *name)
920
{
921
    MonitorDef *md;
922
    for(md = monitor_defs; md->name != NULL; md++) {
923
        if (compare_cmd(name, md->name)) {
924
            if (md->get_value) {
925
                *pval = md->get_value(md);
926
            } else {
927
                *pval = *(uint32_t *)((uint8_t *)cpu_single_env + md->offset);
928
            }
929
            return 0;
930
        }
931
    }
932
    return -1;
933
}
934

    
935
static void next(void)
936
{
937
    if (pch != '\0') {
938
        pch++;
939
        while (isspace(*pch))
940
            pch++;
941
    }
942
}
943

    
944
static int expr_sum(void);
945

    
946
static int expr_unary(void)
947
{
948
    int n;
949
    char *p;
950

    
951
    switch(*pch) {
952
    case '+':
953
        next();
954
        n = expr_unary();
955
        break;
956
    case '-':
957
        next();
958
        n = -expr_unary();
959
        break;
960
    case '~':
961
        next();
962
        n = ~expr_unary();
963
        break;
964
    case '(':
965
        next();
966
        n = expr_sum();
967
        if (*pch != ')') {
968
            expr_error("')' expected");
969
        }
970
        next();
971
        break;
972
    case '\'':
973
        pch++;
974
        if (*pch == '\0')
975
            expr_error("character constant expected");
976
        n = *pch;
977
        pch++;
978
        if (*pch != '\'')
979
            expr_error("missing terminating \' character");
980
        next();
981
        break;
982
    case '$':
983
        {
984
            char buf[128], *q;
985
            
986
            pch++;
987
            q = buf;
988
            while ((*pch >= 'a' && *pch <= 'z') ||
989
                   (*pch >= 'A' && *pch <= 'Z') ||
990
                   (*pch >= '0' && *pch <= '9') ||
991
                   *pch == '_' || *pch == '.') {
992
                if ((q - buf) < sizeof(buf) - 1)
993
                    *q++ = *pch;
994
                pch++;
995
            }
996
            while (isspace(*pch))
997
                pch++;
998
            *q = 0;
999
            if (get_monitor_def(&n, buf))
1000
                expr_error("unknown register");
1001
        }
1002
        break;
1003
    case '\0':
1004
        expr_error("unexpected end of expression");
1005
        n = 0;
1006
        break;
1007
    default:
1008
        n = strtoul(pch, &p, 0);
1009
        if (pch == p) {
1010
            expr_error("invalid char in expression");
1011
        }
1012
        pch = p;
1013
        while (isspace(*pch))
1014
            pch++;
1015
        break;
1016
    }
1017
    return n;
1018
}
1019

    
1020

    
1021
static int expr_prod(void)
1022
{
1023
    int val, val2, op;
1024

    
1025
    val = expr_unary();
1026
    for(;;) {
1027
        op = *pch;
1028
        if (op != '*' && op != '/' && op != '%')
1029
            break;
1030
        next();
1031
        val2 = expr_unary();
1032
        switch(op) {
1033
        default:
1034
        case '*':
1035
            val *= val2;
1036
            break;
1037
        case '/':
1038
        case '%':
1039
            if (val2 == 0) 
1040
                expr_error("division by zero");
1041
            if (op == '/')
1042
                val /= val2;
1043
            else
1044
                val %= val2;
1045
            break;
1046
        }
1047
    }
1048
    return val;
1049
}
1050

    
1051
static int expr_logic(void)
1052
{
1053
    int val, val2, op;
1054

    
1055
    val = expr_prod();
1056
    for(;;) {
1057
        op = *pch;
1058
        if (op != '&' && op != '|' && op != '^')
1059
            break;
1060
        next();
1061
        val2 = expr_prod();
1062
        switch(op) {
1063
        default:
1064
        case '&':
1065
            val &= val2;
1066
            break;
1067
        case '|':
1068
            val |= val2;
1069
            break;
1070
        case '^':
1071
            val ^= val2;
1072
            break;
1073
        }
1074
    }
1075
    return val;
1076
}
1077

    
1078
static int expr_sum(void)
1079
{
1080
    int val, val2, op;
1081

    
1082
    val = expr_logic();
1083
    for(;;) {
1084
        op = *pch;
1085
        if (op != '+' && op != '-')
1086
            break;
1087
        next();
1088
        val2 = expr_logic();
1089
        if (op == '+')
1090
            val += val2;
1091
        else
1092
            val -= val2;
1093
    }
1094
    return val;
1095
}
1096

    
1097
static int get_expr(int *pval, const char **pp)
1098
{
1099
    pch = *pp;
1100
    if (setjmp(expr_env)) {
1101
        *pp = pch;
1102
        return -1;
1103
    }
1104
    while (isspace(*pch))
1105
        pch++;
1106
    *pval = expr_sum();
1107
    *pp = pch;
1108
    return 0;
1109
}
1110

    
1111
static int get_str(char *buf, int buf_size, const char **pp)
1112
{
1113
    const char *p;
1114
    char *q;
1115
    int c;
1116

    
1117
    q = buf;
1118
    p = *pp;
1119
    while (isspace(*p))
1120
        p++;
1121
    if (*p == '\0') {
1122
    fail:
1123
        *q = '\0';
1124
        *pp = p;
1125
        return -1;
1126
    }
1127
    if (*p == '\"') {
1128
        p++;
1129
        while (*p != '\0' && *p != '\"') {
1130
            if (*p == '\\') {
1131
                p++;
1132
                c = *p++;
1133
                switch(c) {
1134
                case 'n':
1135
                    c = '\n';
1136
                    break;
1137
                case 'r':
1138
                    c = '\r';
1139
                    break;
1140
                case '\\':
1141
                case '\'':
1142
                case '\"':
1143
                    break;
1144
                default:
1145
                    qemu_printf("unsupported escape code: '\\%c'\n", c);
1146
                    goto fail;
1147
                }
1148
                if ((q - buf) < buf_size - 1) {
1149
                    *q++ = c;
1150
                }
1151
            } else {
1152
                if ((q - buf) < buf_size - 1) {
1153
                    *q++ = *p;
1154
                }
1155
                p++;
1156
            }
1157
        }
1158
        if (*p != '\"') {
1159
            qemu_printf("unterminated string\n");
1160
            goto fail;
1161
        }
1162
        p++;
1163
    } else {
1164
        while (*p != '\0' && !isspace(*p)) {
1165
            if ((q - buf) < buf_size - 1) {
1166
                *q++ = *p;
1167
            }
1168
            p++;
1169
        }
1170
    }
1171
    *q = '\0';
1172
    *pp = p;
1173
    return 0;
1174
}
1175

    
1176
static int default_fmt_format = 'x';
1177
static int default_fmt_size = 4;
1178

    
1179
#define MAX_ARGS 16
1180

    
1181
static void term_handle_command(const char *cmdline)
1182
{
1183
    const char *p, *pstart, *typestr;
1184
    char *q;
1185
    int c, nb_args, len, i, has_arg;
1186
    term_cmd_t *cmd;
1187
    char cmdname[256];
1188
    char buf[1024];
1189
    void *str_allocated[MAX_ARGS];
1190
    void *args[MAX_ARGS];
1191

    
1192
#ifdef DEBUG
1193
    term_printf("command='%s'\n", cmdline);
1194
#endif
1195
    
1196
    /* extract the command name */
1197
    p = cmdline;
1198
    q = cmdname;
1199
    while (isspace(*p))
1200
        p++;
1201
    if (*p == '\0')
1202
        return;
1203
    pstart = p;
1204
    while (*p != '\0' && *p != '/' && !isspace(*p))
1205
        p++;
1206
    len = p - pstart;
1207
    if (len > sizeof(cmdname) - 1)
1208
        len = sizeof(cmdname) - 1;
1209
    memcpy(cmdname, pstart, len);
1210
    cmdname[len] = '\0';
1211
    
1212
    /* find the command */
1213
    for(cmd = term_cmds; cmd->name != NULL; cmd++) {
1214
        if (compare_cmd(cmdname, cmd->name)) 
1215
            goto found;
1216
    }
1217
    term_printf("unknown command: '%s'\n", cmdname);
1218
    return;
1219
 found:
1220

    
1221
    for(i = 0; i < MAX_ARGS; i++)
1222
        str_allocated[i] = NULL;
1223
    
1224
    /* parse the parameters */
1225
    typestr = cmd->args_type;
1226
    nb_args = 0;
1227
    for(;;) {
1228
        c = *typestr;
1229
        if (c == '\0')
1230
            break;
1231
        typestr++;
1232
        switch(c) {
1233
        case 'F':
1234
        case 'B':
1235
        case 's':
1236
            {
1237
                int ret;
1238
                char *str;
1239
                
1240
                while (isspace(*p)) 
1241
                    p++;
1242
                if (*typestr == '?') {
1243
                    typestr++;
1244
                    if (*p == '\0') {
1245
                        /* no optional string: NULL argument */
1246
                        str = NULL;
1247
                        goto add_str;
1248
                    }
1249
                }
1250
                ret = get_str(buf, sizeof(buf), &p);
1251
                if (ret < 0) {
1252
                    switch(c) {
1253
                    case 'F':
1254
                        term_printf("%s: filename expected\n", cmdname);
1255
                        break;
1256
                    case 'B':
1257
                        term_printf("%s: block device name expected\n", cmdname);
1258
                        break;
1259
                    default:
1260
                        term_printf("%s: string expected\n", cmdname);
1261
                        break;
1262
                    }
1263
                    goto fail;
1264
                }
1265
                str = qemu_malloc(strlen(buf) + 1);
1266
                strcpy(str, buf);
1267
                str_allocated[nb_args] = str;
1268
            add_str:
1269
                if (nb_args >= MAX_ARGS) {
1270
                error_args:
1271
                    term_printf("%s: too many arguments\n", cmdname);
1272
                    goto fail;
1273
                }
1274
                args[nb_args++] = str;
1275
            }
1276
            break;
1277
        case '/':
1278
            {
1279
                int count, format, size;
1280
                
1281
                while (isspace(*p))
1282
                    p++;
1283
                if (*p == '/') {
1284
                    /* format found */
1285
                    p++;
1286
                    count = 1;
1287
                    if (isdigit(*p)) {
1288
                        count = 0;
1289
                        while (isdigit(*p)) {
1290
                            count = count * 10 + (*p - '0');
1291
                            p++;
1292
                        }
1293
                    }
1294
                    size = -1;
1295
                    format = -1;
1296
                    for(;;) {
1297
                        switch(*p) {
1298
                        case 'o':
1299
                        case 'd':
1300
                        case 'u':
1301
                        case 'x':
1302
                        case 'i':
1303
                        case 'c':
1304
                            format = *p++;
1305
                            break;
1306
                        case 'b':
1307
                            size = 1;
1308
                            p++;
1309
                            break;
1310
                        case 'h':
1311
                            size = 2;
1312
                            p++;
1313
                            break;
1314
                        case 'w':
1315
                            size = 4;
1316
                            p++;
1317
                            break;
1318
                        case 'g':
1319
                        case 'L':
1320
                            size = 8;
1321
                            p++;
1322
                            break;
1323
                        default:
1324
                            goto next;
1325
                        }
1326
                    }
1327
                next:
1328
                    if (*p != '\0' && !isspace(*p)) {
1329
                        term_printf("invalid char in format: '%c'\n", *p);
1330
                        goto fail;
1331
                    }
1332
                    if (format < 0)
1333
                        format = default_fmt_format;
1334
                    if (format != 'i') {
1335
                        /* for 'i', not specifying a size gives -1 as size */
1336
                        if (size < 0)
1337
                            size = default_fmt_size;
1338
                    }
1339
                    default_fmt_size = size;
1340
                    default_fmt_format = format;
1341
                } else {
1342
                    count = 1;
1343
                    format = default_fmt_format;
1344
                    if (format != 'i') {
1345
                        size = default_fmt_size;
1346
                    } else {
1347
                        size = -1;
1348
                    }
1349
                }
1350
                if (nb_args + 3 > MAX_ARGS)
1351
                    goto error_args;
1352
                args[nb_args++] = (void*)count;
1353
                args[nb_args++] = (void*)format;
1354
                args[nb_args++] = (void*)size;
1355
            }
1356
            break;
1357
        case 'i':
1358
            {
1359
                int val;
1360
                while (isspace(*p)) 
1361
                    p++;
1362
                if (*typestr == '?' || *typestr == '.') {
1363
                    typestr++;
1364
                    if (*typestr == '?') {
1365
                        if (*p == '\0')
1366
                            has_arg = 0;
1367
                        else
1368
                            has_arg = 1;
1369
                    } else {
1370
                        if (*p == '.') {
1371
                            p++;
1372
                            while (isspace(*p)) 
1373
                                p++;
1374
                            has_arg = 1;
1375
                        } else {
1376
                            has_arg = 0;
1377
                        }
1378
                    }
1379
                    if (nb_args >= MAX_ARGS)
1380
                        goto error_args;
1381
                    args[nb_args++] = (void *)has_arg;
1382
                    if (!has_arg) {
1383
                        if (nb_args >= MAX_ARGS)
1384
                            goto error_args;
1385
                        val = -1;
1386
                        goto add_num;
1387
                    }
1388
                }
1389
                if (get_expr(&val, &p))
1390
                    goto fail;
1391
            add_num:
1392
                if (nb_args >= MAX_ARGS)
1393
                    goto error_args;
1394
                args[nb_args++] = (void *)val;
1395
            }
1396
            break;
1397
        case '-':
1398
            {
1399
                int has_option;
1400
                /* option */
1401
                
1402
                c = *typestr++;
1403
                if (c == '\0')
1404
                    goto bad_type;
1405
                while (isspace(*p)) 
1406
                    p++;
1407
                has_option = 0;
1408
                if (*p == '-') {
1409
                    p++;
1410
                    if (*p != c) {
1411
                        term_printf("%s: unsupported option -%c\n", 
1412
                                    cmdname, *p);
1413
                        goto fail;
1414
                    }
1415
                    p++;
1416
                    has_option = 1;
1417
                }
1418
                if (nb_args >= MAX_ARGS)
1419
                    goto error_args;
1420
                args[nb_args++] = (void *)has_option;
1421
            }
1422
            break;
1423
        default:
1424
        bad_type:
1425
            term_printf("%s: unknown type '%c'\n", cmdname, c);
1426
            goto fail;
1427
        }
1428
    }
1429
    /* check that all arguments were parsed */
1430
    while (isspace(*p))
1431
        p++;
1432
    if (*p != '\0') {
1433
        term_printf("%s: extraneous characters at the end of line\n", 
1434
                    cmdname);
1435
        goto fail;
1436
    }
1437

    
1438
    switch(nb_args) {
1439
    case 0:
1440
        cmd->handler();
1441
        break;
1442
    case 1:
1443
        cmd->handler(args[0]);
1444
        break;
1445
    case 2:
1446
        cmd->handler(args[0], args[1]);
1447
        break;
1448
    case 3:
1449
        cmd->handler(args[0], args[1], args[2]);
1450
        break;
1451
    case 4:
1452
        cmd->handler(args[0], args[1], args[2], args[3]);
1453
        break;
1454
    case 5:
1455
        cmd->handler(args[0], args[1], args[2], args[3], args[4]);
1456
        break;
1457
    case 6:
1458
        cmd->handler(args[0], args[1], args[2], args[3], args[4], args[5]);
1459
        break;
1460
    default:
1461
        term_printf("unsupported number of arguments: %d\n", nb_args);
1462
        goto fail;
1463
    }
1464
 fail:
1465
    for(i = 0; i < MAX_ARGS; i++)
1466
        qemu_free(str_allocated[i]);
1467
    return;
1468
}
1469

    
1470
static void cmd_completion(const char *name, const char *list)
1471
{
1472
    const char *p, *pstart;
1473
    char cmd[128];
1474
    int len;
1475

    
1476
    p = list;
1477
    for(;;) {
1478
        pstart = p;
1479
        p = strchr(p, '|');
1480
        if (!p)
1481
            p = pstart + strlen(pstart);
1482
        len = p - pstart;
1483
        if (len > sizeof(cmd) - 2)
1484
            len = sizeof(cmd) - 2;
1485
        memcpy(cmd, pstart, len);
1486
        cmd[len] = '\0';
1487
        if (name[0] == '\0' || !strncmp(name, cmd, strlen(name))) {
1488
            add_completion(cmd);
1489
        }
1490
        if (*p == '\0')
1491
            break;
1492
        p++;
1493
    }
1494
}
1495

    
1496
static void file_completion(const char *input)
1497
{
1498
    DIR *ffs;
1499
    struct dirent *d;
1500
    char path[1024];
1501
    char file[1024], file_prefix[1024];
1502
    int input_path_len;
1503
    const char *p;
1504

    
1505
    p = strrchr(input, '/'); 
1506
    if (!p) {
1507
        input_path_len = 0;
1508
        pstrcpy(file_prefix, sizeof(file_prefix), input);
1509
        strcpy(path, ".");
1510
    } else {
1511
        input_path_len = p - input + 1;
1512
        memcpy(path, input, input_path_len);
1513
        if (input_path_len > sizeof(path) - 1)
1514
            input_path_len = sizeof(path) - 1;
1515
        path[input_path_len] = '\0';
1516
        pstrcpy(file_prefix, sizeof(file_prefix), p + 1);
1517
    }
1518
#ifdef DEBUG_COMPLETION
1519
    term_printf("input='%s' path='%s' prefix='%s'\n", input, path, file_prefix);
1520
#endif
1521
    ffs = opendir(path);
1522
    if (!ffs)
1523
        return;
1524
    for(;;) {
1525
        struct stat sb;
1526
        d = readdir(ffs);
1527
        if (!d)
1528
            break;
1529
        if (strstart(d->d_name, file_prefix, NULL)) {
1530
            memcpy(file, input, input_path_len);
1531
            strcpy(file + input_path_len, d->d_name);
1532
            /* stat the file to find out if it's a directory.
1533
             * In that case add a slash to speed up typing long paths
1534
             */
1535
            stat(file, &sb);
1536
            if(S_ISDIR(sb.st_mode))
1537
                strcat(file, "/");
1538
            add_completion(file);
1539
        }
1540
    }
1541
    closedir(ffs);
1542
}
1543

    
1544
static void block_completion_it(void *opaque, const char *name)
1545
{
1546
    const char *input = opaque;
1547

    
1548
    if (input[0] == '\0' ||
1549
        !strncmp(name, (char *)input, strlen(input))) {
1550
        add_completion(name);
1551
    }
1552
}
1553

    
1554
/* NOTE: this parser is an approximate form of the real command parser */
1555
static void parse_cmdline(const char *cmdline,
1556
                         int *pnb_args, char **args)
1557
{
1558
    const char *p;
1559
    int nb_args, ret;
1560
    char buf[1024];
1561

    
1562
    p = cmdline;
1563
    nb_args = 0;
1564
    for(;;) {
1565
        while (isspace(*p))
1566
            p++;
1567
        if (*p == '\0')
1568
            break;
1569
        if (nb_args >= MAX_ARGS)
1570
            break;
1571
        ret = get_str(buf, sizeof(buf), &p);
1572
        args[nb_args] = qemu_strdup(buf);
1573
        nb_args++;
1574
        if (ret < 0)
1575
            break;
1576
    }
1577
    *pnb_args = nb_args;
1578
}
1579

    
1580
static void find_completion(const char *cmdline)
1581
{
1582
    const char *cmdname;
1583
    char *args[MAX_ARGS];
1584
    int nb_args, i, len;
1585
    const char *ptype, *str;
1586
    term_cmd_t *cmd;
1587

    
1588
    parse_cmdline(cmdline, &nb_args, args);
1589
#ifdef DEBUG_COMPLETION
1590
    for(i = 0; i < nb_args; i++) {
1591
        term_printf("arg%d = '%s'\n", i, (char *)args[i]);
1592
    }
1593
#endif
1594

    
1595
    /* if the line ends with a space, it means we want to complete the
1596
       next arg */
1597
    len = strlen(cmdline);
1598
    if (len > 0 && isspace(cmdline[len - 1])) {
1599
        if (nb_args >= MAX_ARGS)
1600
            return;
1601
        args[nb_args++] = qemu_strdup("");
1602
    }
1603
    if (nb_args <= 1) {
1604
        /* command completion */
1605
        if (nb_args == 0)
1606
            cmdname = "";
1607
        else
1608
            cmdname = args[0];
1609
        completion_index = strlen(cmdname);
1610
        for(cmd = term_cmds; cmd->name != NULL; cmd++) {
1611
            cmd_completion(cmdname, cmd->name);
1612
        }
1613
    } else {
1614
        /* find the command */
1615
        for(cmd = term_cmds; cmd->name != NULL; cmd++) {
1616
            if (compare_cmd(args[0], cmd->name))
1617
                goto found;
1618
        }
1619
        return;
1620
    found:
1621
        ptype = cmd->args_type;
1622
        for(i = 0; i < nb_args - 2; i++) {
1623
            if (*ptype != '\0') {
1624
                ptype++;
1625
                while (*ptype == '?')
1626
                    ptype++;
1627
            }
1628
        }
1629
        str = args[nb_args - 1];
1630
        switch(*ptype) {
1631
        case 'F':
1632
            /* file completion */
1633
            completion_index = strlen(str);
1634
            file_completion(str);
1635
            break;
1636
        case 'B':
1637
            /* block device name completion */
1638
            completion_index = strlen(str);
1639
            bdrv_iterate(block_completion_it, (void *)str);
1640
            break;
1641
        default:
1642
            break;
1643
        }
1644
    }
1645
    for(i = 0; i < nb_args; i++)
1646
        qemu_free(args[i]);
1647
}
1648

    
1649
static void term_show_prompt2(void)
1650
{
1651
    term_printf("(qemu) ");
1652
    fflush(stdout);
1653
    term_last_cmd_buf_index = 0;
1654
    term_last_cmd_buf_size = 0;
1655
    term_esc_state = IS_NORM;
1656
}
1657

    
1658
static void term_show_prompt(void)
1659
{
1660
    term_show_prompt2();
1661
    term_cmd_buf_index = 0;
1662
    term_cmd_buf_size = 0;
1663
}
1664

    
1665
/* update the displayed command line */
1666
static void term_update(void)
1667
{
1668
    int i, delta;
1669

    
1670
    if (term_cmd_buf_size != term_last_cmd_buf_size ||
1671
        memcmp(term_cmd_buf, term_last_cmd_buf, term_cmd_buf_size) != 0) {
1672
        for(i = 0; i < term_last_cmd_buf_index; i++) {
1673
            term_printf("\033[D");
1674
        }
1675
        term_cmd_buf[term_cmd_buf_size] = '\0';
1676
        term_printf("%s", term_cmd_buf);
1677
        term_printf("\033[K");
1678
        memcpy(term_last_cmd_buf, term_cmd_buf, term_cmd_buf_size);
1679
        term_last_cmd_buf_size = term_cmd_buf_size;
1680
        term_last_cmd_buf_index = term_cmd_buf_size;
1681
    }
1682
    if (term_cmd_buf_index != term_last_cmd_buf_index) {
1683
        delta = term_cmd_buf_index - term_last_cmd_buf_index;
1684
        if (delta > 0) {
1685
            for(i = 0;i < delta; i++) {
1686
                term_printf("\033[C");
1687
            }
1688
        } else {
1689
            delta = -delta;
1690
            for(i = 0;i < delta; i++) {
1691
                term_printf("\033[D");
1692
            }
1693
        }
1694
        term_last_cmd_buf_index = term_cmd_buf_index;
1695
    }
1696
    term_flush();
1697
}
1698

    
1699
static void term_insert_char(int ch)
1700
{
1701
    if (term_cmd_buf_index < TERM_CMD_BUF_SIZE) {
1702
        memmove(term_cmd_buf + term_cmd_buf_index + 1,
1703
                term_cmd_buf + term_cmd_buf_index,
1704
                term_cmd_buf_size - term_cmd_buf_index);
1705
        term_cmd_buf[term_cmd_buf_index] = ch;
1706
        term_cmd_buf_size++;
1707
        term_cmd_buf_index++;
1708
    }
1709
}
1710

    
1711
static void term_backward_char(void)
1712
{
1713
    if (term_cmd_buf_index > 0) {
1714
        term_cmd_buf_index--;
1715
    }
1716
}
1717

    
1718
static void term_forward_char(void)
1719
{
1720
    if (term_cmd_buf_index < term_cmd_buf_size) {
1721
        term_cmd_buf_index++;
1722
    }
1723
}
1724

    
1725
static void term_delete_char(void)
1726
{
1727
    if (term_cmd_buf_index < term_cmd_buf_size) {
1728
        memmove(term_cmd_buf + term_cmd_buf_index,
1729
                term_cmd_buf + term_cmd_buf_index + 1,
1730
                term_cmd_buf_size - term_cmd_buf_index - 1);
1731
        term_cmd_buf_size--;
1732
    }
1733
}
1734

    
1735
static void term_backspace(void)
1736
{
1737
    if (term_cmd_buf_index > 0) {
1738
        term_backward_char();
1739
        term_delete_char();
1740
    }
1741
}
1742

    
1743
static void term_bol(void)
1744
{
1745
    term_cmd_buf_index = 0;
1746
}
1747

    
1748
static void term_eol(void)
1749
{
1750
    term_cmd_buf_index = term_cmd_buf_size;
1751
}
1752

    
1753
static void term_up_char(void)
1754
{
1755
    int idx;
1756

    
1757
    if (term_hist_entry == 0)
1758
        return;
1759
    if (term_hist_entry == -1) {
1760
        /* Find latest entry */
1761
        for (idx = 0; idx < TERM_MAX_CMDS; idx++) {
1762
            if (term_history[idx] == NULL)
1763
                break;
1764
        }
1765
        term_hist_entry = idx;
1766
    }
1767
    term_hist_entry--;
1768
    if (term_hist_entry >= 0) {
1769
        pstrcpy(term_cmd_buf, sizeof(term_cmd_buf), 
1770
                term_history[term_hist_entry]);
1771
        term_cmd_buf_index = term_cmd_buf_size = strlen(term_cmd_buf);
1772
    }
1773
}
1774

    
1775
static void term_down_char(void)
1776
{
1777
    if (term_hist_entry == TERM_MAX_CMDS - 1 || term_hist_entry == -1)
1778
        return;
1779
    if (term_history[++term_hist_entry] != NULL) {
1780
        pstrcpy(term_cmd_buf, sizeof(term_cmd_buf),
1781
                term_history[term_hist_entry]);
1782
    } else {
1783
        term_hist_entry = -1;
1784
    }
1785
    term_cmd_buf_index = term_cmd_buf_size = strlen(term_cmd_buf);
1786
}
1787

    
1788
static void term_hist_add(const char *cmdline)
1789
{
1790
    char *hist_entry, *new_entry;
1791
    int idx;
1792

    
1793
    if (cmdline[0] == '\0')
1794
        return;
1795
    new_entry = NULL;
1796
    if (term_hist_entry != -1) {
1797
        /* We were editing an existing history entry: replace it */
1798
        hist_entry = term_history[term_hist_entry];
1799
        idx = term_hist_entry;
1800
        if (strcmp(hist_entry, cmdline) == 0) {
1801
            goto same_entry;
1802
        }
1803
    }
1804
    /* Search cmdline in history buffers */
1805
    for (idx = 0; idx < TERM_MAX_CMDS; idx++) {
1806
        hist_entry = term_history[idx];
1807
        if (hist_entry == NULL)
1808
            break;
1809
        if (strcmp(hist_entry, cmdline) == 0) {
1810
        same_entry:
1811
            new_entry = hist_entry;
1812
            /* Put this entry at the end of history */
1813
            memmove(&term_history[idx], &term_history[idx + 1],
1814
                    &term_history[TERM_MAX_CMDS] - &term_history[idx + 1]);
1815
            term_history[TERM_MAX_CMDS - 1] = NULL;
1816
            for (; idx < TERM_MAX_CMDS; idx++) {
1817
                if (term_history[idx] == NULL)
1818
                    break;
1819
            }
1820
            break;
1821
        }
1822
    }
1823
    if (idx == TERM_MAX_CMDS) {
1824
        /* Need to get one free slot */
1825
        free(term_history[0]);
1826
        memcpy(term_history, &term_history[1],
1827
               &term_history[TERM_MAX_CMDS] - &term_history[1]);
1828
        term_history[TERM_MAX_CMDS - 1] = NULL;
1829
        idx = TERM_MAX_CMDS - 1;
1830
    }
1831
    if (new_entry == NULL)
1832
        new_entry = strdup(cmdline);
1833
    term_history[idx] = new_entry;
1834
    term_hist_entry = -1;
1835
}
1836

    
1837
/* completion support */
1838

    
1839
static void add_completion(const char *str)
1840
{
1841
    if (nb_completions < NB_COMPLETIONS_MAX) {
1842
        completions[nb_completions++] = qemu_strdup(str);
1843
    }
1844
}
1845

    
1846
static void term_completion(void)
1847
{
1848
    int len, i, j, max_width, nb_cols;
1849
    char *cmdline;
1850

    
1851
    nb_completions = 0;
1852
    
1853
    cmdline = qemu_malloc(term_cmd_buf_index + 1);
1854
    if (!cmdline)
1855
        return;
1856
    memcpy(cmdline, term_cmd_buf, term_cmd_buf_index);
1857
    cmdline[term_cmd_buf_index] = '\0';
1858
    find_completion(cmdline);
1859
    qemu_free(cmdline);
1860

    
1861
    /* no completion found */
1862
    if (nb_completions <= 0)
1863
        return;
1864
    if (nb_completions == 1) {
1865
        len = strlen(completions[0]);
1866
        for(i = completion_index; i < len; i++) {
1867
            term_insert_char(completions[0][i]);
1868
        }
1869
        /* extra space for next argument. XXX: make it more generic */
1870
        if (len > 0 && completions[0][len - 1] != '/')
1871
            term_insert_char(' ');
1872
    } else {
1873
        term_printf("\n");
1874
        max_width = 0;
1875
        for(i = 0; i < nb_completions; i++) {
1876
            len = strlen(completions[i]);
1877
            if (len > max_width)
1878
                max_width = len;
1879
        }
1880
        max_width += 2;
1881
        if (max_width < 10)
1882
            max_width = 10;
1883
        else if (max_width > 80)
1884
            max_width = 80;
1885
        nb_cols = 80 / max_width;
1886
        j = 0;
1887
        for(i = 0; i < nb_completions; i++) {
1888
            term_printf("%-*s", max_width, completions[i]);
1889
            if (++j == nb_cols || i == (nb_completions - 1)) {
1890
                term_printf("\n");
1891
                j = 0;
1892
            }
1893
        }
1894
        term_show_prompt2();
1895
    }
1896
}
1897

    
1898
/* return true if command handled */
1899
static void term_handle_byte(int ch)
1900
{
1901
    switch(term_esc_state) {
1902
    case IS_NORM:
1903
        switch(ch) {
1904
        case 1:
1905
            term_bol();
1906
            break;
1907
        case 4:
1908
            term_delete_char();
1909
            break;
1910
        case 5:
1911
            term_eol();
1912
            break;
1913
        case 9:
1914
            term_completion();
1915
            break;
1916
        case 10:
1917
        case 13:
1918
            term_cmd_buf[term_cmd_buf_size] = '\0';
1919
            term_hist_add(term_cmd_buf);
1920
            term_printf("\n");
1921
            term_handle_command(term_cmd_buf);
1922
            term_show_prompt();
1923
            break;
1924
        case 27:
1925
            term_esc_state = IS_ESC;
1926
            break;
1927
        case 127:
1928
        case 8:
1929
            term_backspace();
1930
            break;
1931
        case 155:
1932
            term_esc_state = IS_CSI;
1933
            break;
1934
        default:
1935
            if (ch >= 32) {
1936
                term_insert_char(ch);
1937
            }
1938
            break;
1939
        }
1940
        break;
1941
    case IS_ESC:
1942
        if (ch == '[') {
1943
            term_esc_state = IS_CSI;
1944
            term_esc_param = 0;
1945
        } else {
1946
            term_esc_state = IS_NORM;
1947
        }
1948
        break;
1949
    case IS_CSI:
1950
        switch(ch) {
1951
        case 'A':
1952
        case 'F':
1953
            term_up_char();
1954
            break;
1955
        case 'B':
1956
        case 'E':
1957
            term_down_char();
1958
            break;
1959
        case 'D':
1960
            term_backward_char();
1961
            break;
1962
        case 'C':
1963
            term_forward_char();
1964
            break;
1965
        case '0' ... '9':
1966
            term_esc_param = term_esc_param * 10 + (ch - '0');
1967
            goto the_end;
1968
        case '~':
1969
            switch(term_esc_param) {
1970
            case 1:
1971
                term_bol();
1972
                break;
1973
            case 3:
1974
                term_delete_char();
1975
                break;
1976
            case 4:
1977
                term_eol();
1978
                break;
1979
            }
1980
            break;
1981
        default:
1982
            break;
1983
        }
1984
        term_esc_state = IS_NORM;
1985
    the_end:
1986
        break;
1987
    }
1988
    term_update();
1989
}
1990

    
1991
static int term_can_read(void *opaque)
1992
{
1993
    return 128;
1994
}
1995

    
1996
static void term_read(void *opaque, const uint8_t *buf, int size)
1997
{
1998
    int i;
1999
    for(i = 0; i < size; i++)
2000
        term_handle_byte(buf[i]);
2001
}
2002

    
2003
void monitor_init(CharDriverState *hd, int show_banner)
2004
{
2005
    monitor_hd = hd;
2006
    if (show_banner) {
2007
        term_printf("QEMU %s monitor - type 'help' for more information\n",
2008
                    QEMU_VERSION);
2009
        term_show_prompt();
2010
    }
2011
    term_hist_entry = -1;
2012
    qemu_chr_add_read_handler(hd, term_can_read, term_read, NULL);
2013
}