]>
git.proxmox.com Git - mirror_qemu.git/blob - monitor.c
4 * Copyright (c) 2003-2004 Fabrice Bellard
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
28 #define TERM_CMD_BUF_SIZE 4095
35 #define printf do_not_use_printf
37 static char term_cmd_buf
[TERM_CMD_BUF_SIZE
+ 1];
38 static int term_cmd_buf_index
;
39 static int term_cmd_buf_size
;
40 static int term_esc_state
;
41 static int term_esc_param
;
43 typedef struct term_cmd_t
{
45 void (*handler
)(int argc
, const char **argv
);
50 static term_cmd_t term_cmds
[];
51 static term_cmd_t info_cmds
[];
53 void term_printf(const char *fmt
, ...)
66 static int compare_cmd(const char *name
, const char *list
)
68 const char *p
, *pstart
;
76 p
= pstart
+ strlen(pstart
);
77 if ((p
- pstart
) == len
&& !memcmp(pstart
, name
, len
))
86 static void help_cmd1(term_cmd_t
*cmds
, const char *prefix
, const char *name
)
90 for(cmd
= cmds
; cmd
->name
!= NULL
; cmd
++) {
91 if (!name
|| !strcmp(name
, cmd
->name
))
92 term_printf("%s%s %s -- %s\n", prefix
, cmd
->name
, cmd
->params
, cmd
->help
);
96 static void help_cmd(const char *name
)
98 if (name
&& !strcmp(name
, "info")) {
99 help_cmd1(info_cmds
, "info ", NULL
);
101 help_cmd1(term_cmds
, "", name
);
102 if (name
&& !strcmp(name
, "log")) {
104 term_printf("Log items (comma separated):\n");
105 term_printf("%-10s %s\n", "none", "remove all logs");
106 for(item
= cpu_log_items
; item
->mask
!= 0; item
++) {
107 term_printf("%-10s %s\n", item
->name
, item
->help
);
113 static void do_help(int argc
, const char **argv
)
118 static void do_commit(int argc
, const char **argv
)
122 for (i
= 0; i
< MAX_DISKS
; i
++) {
124 bdrv_commit(bs_table
[i
]);
128 static void do_info(int argc
, const char **argv
)
136 for(cmd
= info_cmds
; cmd
->name
!= NULL
; cmd
++) {
137 if (compare_cmd(argv
[1], cmd
->name
))
144 cmd
->handler(argc
, argv
);
147 static void do_info_network(int argc
, const char **argv
)
152 for(i
= 0; i
< nb_nics
; i
++) {
154 term_printf("%d: ifname=%s macaddr=", i
, nd
->ifname
);
155 for(j
= 0; j
< 6; j
++) {
158 term_printf("%02x", nd
->macaddr
[j
]);
164 static void do_info_block(int argc
, const char **argv
)
169 static void do_quit(int argc
, const char **argv
)
174 static int eject_device(BlockDriverState
*bs
, int force
)
176 if (bdrv_is_inserted(bs
)) {
178 if (!bdrv_is_removable(bs
)) {
179 term_printf("device is not removable\n");
182 if (bdrv_is_locked(bs
)) {
183 term_printf("device is locked\n");
192 static void do_eject(int argc
, const char **argv
)
194 BlockDriverState
*bs
;
205 if (!strcmp(*parg
, "-f")) {
211 bs
= bdrv_find(*parg
);
213 term_printf("device not found\n");
216 eject_device(bs
, force
);
219 static void do_change(int argc
, const char **argv
)
221 BlockDriverState
*bs
;
227 bs
= bdrv_find(argv
[1]);
229 term_printf("device not found\n");
232 if (eject_device(bs
, 0) < 0)
234 bdrv_open(bs
, argv
[2], 0);
237 static void do_screen_dump(int argc
, const char **argv
)
243 vga_screen_dump(argv
[1]);
246 static void do_log(int argc
, const char **argv
)
252 if (!strcmp(argv
[1], "none")) {
255 mask
= cpu_str_to_log_mask(argv
[1]);
265 static void do_savevm(int argc
, const char **argv
)
271 if (qemu_savevm(argv
[1]) < 0)
272 term_printf("I/O error when saving VM to '%s'\n", argv
[1]);
275 static void do_loadvm(int argc
, const char **argv
)
281 if (qemu_loadvm(argv
[1]) < 0)
282 term_printf("I/O error when loading VM from '%s'\n", argv
[1]);
285 static void do_stop(int argc
, const char **argv
)
287 vm_stop(EXCP_INTERRUPT
);
290 static void do_cont(int argc
, const char **argv
)
295 #ifdef CONFIG_GDBSTUB
296 static void do_gdbserver(int argc
, const char **argv
)
300 port
= DEFAULT_GDBSTUB_PORT
;
302 port
= atoi(argv
[1]);
303 if (gdbserver_start(port
) < 0) {
304 qemu_printf("Could not open gdbserver socket on port %d\n", port
);
306 qemu_printf("Waiting gdb connection on port %d\n", port
);
311 static term_cmd_t term_cmds
[] = {
313 "[cmd]", "show the help" },
314 { "commit", do_commit
,
315 "", "commit changes to the disk images (if -snapshot is used)" },
317 "subcommand", "show various information about the system state" },
319 "", "quit the emulator" },
321 "[-f] device", "eject a removable media (use -f to force it)" },
322 { "change", do_change
,
323 "device filename", "change a removable media" },
324 { "screendump", do_screen_dump
,
325 "filename", "save screen into PPM image 'filename'" },
327 "item1[,...]", "activate logging of the specified items to '/tmp/qemu.log'" },
328 { "savevm", do_savevm
,
329 "filename", "save the whole virtual machine state to 'filename'" },
330 { "loadvm", do_loadvm
,
331 "filename", "restore the whole virtual machine state from 'filename'" },
332 { "stop", do_stop
, "", "stop emulation", },
333 { "c|cont", do_cont
, "", "resume emulation", },
334 #ifdef CONFIG_GDBSTUB
335 { "gdbserver", do_gdbserver
, "[port]", "start gdbserver session (default port=1234)", },
340 static term_cmd_t info_cmds
[] = {
341 { "network", do_info_network
,
342 "", "show the network state" },
343 { "block", do_info_block
,
344 "", "show the block devices" },
348 static void term_handle_command(char *cmdline
)
352 const char *args
[MAX_ARGS
+ 1];
356 term_printf("command='%s'\n", cmdline
);
359 /* split command in words */
368 while (*p
!= '\0' && !isspace(*p
))
372 if (argc
>= MAX_ARGS
)
380 for(i
=0;i
<argc
;i
++) {
381 term_printf(" '%s'", args
[i
]);
387 for(cmd
= term_cmds
; cmd
->name
!= NULL
; cmd
++) {
388 if (compare_cmd(args
[0], cmd
->name
))
391 term_printf("unknown command: '%s'\n", args
[0]);
394 cmd
->handler(argc
, args
);
397 static void term_show_prompt(void)
399 term_printf("(qemu) ");
401 term_cmd_buf_index
= 0;
402 term_cmd_buf_size
= 0;
403 term_esc_state
= IS_NORM
;
406 static void term_insert_char(int ch
)
408 if (term_cmd_buf_index
< TERM_CMD_BUF_SIZE
) {
409 memmove(term_cmd_buf
+ term_cmd_buf_index
+ 1,
410 term_cmd_buf
+ term_cmd_buf_index
,
411 term_cmd_buf_size
- term_cmd_buf_index
);
412 term_cmd_buf
[term_cmd_buf_index
] = ch
;
414 term_printf("\033[@%c", ch
);
415 term_cmd_buf_index
++;
420 static void term_backward_char(void)
422 if (term_cmd_buf_index
> 0) {
423 term_cmd_buf_index
--;
424 term_printf("\033[D");
429 static void term_forward_char(void)
431 if (term_cmd_buf_index
< term_cmd_buf_size
) {
432 term_cmd_buf_index
++;
433 term_printf("\033[C");
438 static void term_delete_char(void)
440 if (term_cmd_buf_index
< term_cmd_buf_size
) {
441 memmove(term_cmd_buf
+ term_cmd_buf_index
,
442 term_cmd_buf
+ term_cmd_buf_index
+ 1,
443 term_cmd_buf_size
- term_cmd_buf_index
- 1);
444 term_printf("\033[P");
450 static void term_backspace(void)
452 if (term_cmd_buf_index
> 0) {
453 term_backward_char();
458 static void term_bol(void)
460 while (term_cmd_buf_index
> 0)
461 term_backward_char();
464 static void term_eol(void)
466 while (term_cmd_buf_index
< term_cmd_buf_size
)
470 /* return true if command handled */
471 static void term_handle_byte(int ch
)
473 switch(term_esc_state
) {
484 term_cmd_buf
[term_cmd_buf_size
] = '\0';
486 term_handle_command(term_cmd_buf
);
490 term_esc_state
= IS_ESC
;
498 term_insert_char(ch
);
505 term_esc_state
= IS_CSI
;
508 term_esc_state
= IS_NORM
;
514 term_backward_char();
520 term_esc_param
= term_esc_param
* 10 + (ch
- '0');
523 switch(term_esc_param
) {
538 term_esc_state
= IS_NORM
;
544 /*************************************************************/
545 /* serial console support */
547 #define TERM_ESCAPE 0x01 /* ctrl-a is used for escape */
549 static int term_got_escape
, term_command
;
551 void term_print_help(void)
554 "C-a h print this help\n"
555 "C-a x exit emulatior\n"
556 "C-a s save disk data back to file (if -snapshot)\n"
557 "C-a b send break (magic sysrq)\n"
558 "C-a c switch between console and monitor\n"
563 /* called when a char is received */
564 static void term_received_byte(int ch
)
566 if (!serial_console
) {
567 /* if no serial console, handle every command */
568 term_handle_byte(ch
);
570 if (term_got_escape
) {
582 for (i
= 0; i
< MAX_DISKS
; i
++) {
584 bdrv_commit(bs_table
[i
]);
590 serial_receive_break(serial_console
);
603 } else if (ch
== TERM_ESCAPE
) {
608 term_handle_byte(ch
);
611 serial_receive_byte(serial_console
, ch
);
617 static int term_can_read(void *opaque
)
619 if (serial_console
) {
620 return serial_can_receive(serial_console
);
626 static void term_read(void *opaque
, const uint8_t *buf
, int size
)
629 for(i
= 0; i
< size
; i
++)
630 term_received_byte(buf
[i
]);
633 void monitor_init(void)
635 if (!serial_console
) {
636 term_printf("QEMU %s monitor - type 'help' for more information\n",
640 qemu_add_fd_read_handler(0, term_can_read
, term_read
, NULL
);