1
2
/*
* QEMU monitor
ths
authored
18 years ago
3
*
4
* Copyright ( c ) 2003 - 2004 Fabrice Bellard
ths
authored
18 years ago
5
*
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
* Permission is hereby granted , free of charge , to any person obtaining a copy
* of this software and associated documentation files ( the "Software" ), to deal
* in the Software without restriction , including without limitation the rights
* to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
* copies of the Software , and to permit persons to whom the Software is
* furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED "AS IS" , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE .
*/
24
# include < dirent . h >
25
26
27
28
29
# include "hw/hw.h"
# include "hw/usb.h"
# include "hw/pcmcia.h"
# include "hw/pc.h"
# include "hw/pci.h"
30
# include "hw/watchdog.h"
31
32
33
34
# include "gdbstub.h"
# include "net.h"
# include "qemu-char.h"
# include "sysemu.h"
35
36
# include "monitor.h"
# include "readline.h"
37
38
39
# include "console.h"
# include "block.h"
# include "audio/audio.h"
40
# include "disas.h"
41
# include "balloon.h"
42
# include "qemu-timer.h"
43
# include "migration.h"
44
# include "kvm.h"
45
# include "acl.h"
ths
authored
17 years ago
46
47
// # define DEBUG
48
// # define DEBUG_COMPLETION
49
50
51
/*
* Supported types :
ths
authored
18 years ago
52
*
53
* 'F' filename
54
* 'B' block device name
55
* 's' string ( accept optional quote )
56
57
* 'i' 32 bit integer
* 'l' target long ( 32 or 64 bit )
58
59
60
61
62
63
* '/' optional gdb - like print format ( like "/10x" )
*
* '?' optional type ( for 'F' , 's' and 'i' )
*
*/
64
typedef struct mon_cmd_t {
65
const char * name ;
66
const char * args_type ;
67
void * handler ;
68
69
const char * params ;
const char * help ;
70
} mon_cmd_t ;
71
72
73
struct Monitor {
CharDriverState * chr ;
74
75
76
77
78
79
80
81
int flags ;
int suspend_cnt ;
uint8_t outbuf [ 1024 ];
int outbuf_index ;
ReadLineState * rs ;
CPUState * mon_cpu ;
BlockDriverCompletionFunc * password_completion_cb ;
void * password_opaque ;
82
83
84
85
LIST_ENTRY ( Monitor ) entry ;
};
static LIST_HEAD ( mon_list , Monitor ) mon_list ;
86
87
88
static const mon_cmd_t mon_cmds [];
static const mon_cmd_t info_cmds [];
89
90
Monitor * cur_mon = NULL ;
91
92
93
static void monitor_command_cb ( Monitor * mon , const char * cmdline ,
void * opaque );
94
95
96
97
98
99
100
static void monitor_read_command ( Monitor * mon , int show_prompt )
{
readline_start ( mon -> rs , "(qemu) " , 0 , monitor_command_cb , NULL );
if ( show_prompt )
readline_show_prompt ( mon -> rs );
}
101
102
103
static int monitor_read_password ( Monitor * mon , ReadLineFunc * readline_func ,
void * opaque )
104
{
105
106
107
108
109
110
111
112
if ( mon -> rs ) {
readline_start ( mon -> rs , "Password: " , 1 , readline_func , opaque );
/* prompt is printed on return from the command handler */
return 0 ;
} else {
monitor_printf ( mon , "terminal does not support password prompting \n " );
return - ENOTTY ;
}
113
114
}
115
void monitor_flush ( Monitor * mon )
116
{
117
118
119
if ( mon && mon -> outbuf_index != 0 && mon -> chr -> focus == 0 ) {
qemu_chr_write ( mon -> chr , mon -> outbuf , mon -> outbuf_index );
mon -> outbuf_index = 0 ;
120
121
122
123
}
}
/* flush at every end of line or if the buffer is full */
124
static void monitor_puts ( Monitor * mon , const char * str )
125
{
ths
authored
17 years ago
126
char c ;
127
128
129
130
if ( ! mon )
return ;
131
132
133
134
for (;;) {
c = * str ++ ;
if ( c == '\0' )
break ;
135
if ( c == '\n' )
136
137
138
139
mon -> outbuf [ mon -> outbuf_index ++ ] = '\r' ;
mon -> outbuf [ mon -> outbuf_index ++ ] = c ;
if ( mon -> outbuf_index >= ( sizeof ( mon -> outbuf ) - 1 )
|| c == '\n' )
140
monitor_flush ( mon );
141
142
143
}
}
144
void monitor_vprintf ( Monitor * mon , const char * fmt , va_list ap )
145
{
146
147
char buf [ 4096 ];
vsnprintf ( buf , sizeof ( buf ), fmt , ap );
148
monitor_puts ( mon , buf );
149
150
}
151
void monitor_printf ( Monitor * mon , const char * fmt , ...)
152
{
153
154
va_list ap ;
va_start ( ap , fmt );
155
monitor_vprintf ( mon , fmt , ap );
156
va_end ( ap );
157
158
}
159
void monitor_print_filename ( Monitor * mon , const char * filename )
ths
authored
18 years ago
160
161
162
163
{
int i ;
for ( i = 0 ; filename [ i ]; i ++ ) {
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
switch ( filename [ i ]) {
case ' ' :
case '"' :
case '\\' :
monitor_printf ( mon , " \\ %c" , filename [ i ]);
break ;
case '\t' :
monitor_printf ( mon , " \\ t" );
break ;
case '\r' :
monitor_printf ( mon , " \\ r" );
break ;
case '\n' :
monitor_printf ( mon , " \\ n" );
break ;
default :
monitor_printf ( mon , "%c" , filename [ i ]);
break ;
}
ths
authored
18 years ago
183
184
185
}
}
186
187
188
189
static int monitor_fprintf ( FILE * stream , const char * fmt , ...)
{
va_list ap ;
va_start ( ap , fmt );
190
monitor_vprintf (( Monitor * ) stream , fmt , ap );
191
192
193
194
va_end ( ap );
return 0 ;
}
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
static int compare_cmd ( const char * name , const char * list )
{
const char * p , * pstart ;
int len ;
len = strlen ( name );
p = list ;
for (;;) {
pstart = p ;
p = strchr ( p , '|' );
if ( ! p )
p = pstart + strlen ( pstart );
if (( p - pstart ) == len && ! memcmp ( pstart , name , len ))
return 1 ;
if ( * p == '\0' )
break ;
p ++ ;
}
return 0 ;
}
215
216
static void help_cmd_dump ( Monitor * mon , const mon_cmd_t * cmds ,
const char * prefix , const char * name )
217
{
218
const mon_cmd_t * cmd ;
219
220
221
for ( cmd = cmds ; cmd -> name != NULL ; cmd ++ ) {
if ( ! name || ! strcmp ( name , cmd -> name ))
222
223
monitor_printf ( mon , "%s%s %s -- %s \n " , prefix , cmd -> name ,
cmd -> params , cmd -> help );
224
225
226
}
}
227
static void help_cmd ( Monitor * mon , const char * name )
228
229
{
if ( name && ! strcmp ( name , "info" )) {
230
help_cmd_dump ( mon , info_cmds , "info " , NULL );
231
} else {
232
help_cmd_dump ( mon , mon_cmds , "" , name );
233
if ( name && ! strcmp ( name , "log" )) {
234
const CPULogItem * item ;
235
236
monitor_printf ( mon , "Log items (comma separated): \n " );
monitor_printf ( mon , "%-10s %s \n " , "none" , "remove all logs" );
237
for ( item = cpu_log_items ; item -> mask != 0 ; item ++ ) {
238
monitor_printf ( mon , "%-10s %s \n " , item -> name , item -> help );
239
240
}
}
241
242
243
}
}
244
static void do_commit ( Monitor * mon , const char * device )
245
{
246
int i , all_devices ;
247
248
all_devices = ! strcmp ( device , "all" );
ths
authored
17 years ago
249
for ( i = 0 ; i < nb_drives ; i ++ ) {
ths
authored
18 years ago
250
if ( all_devices ||
ths
authored
17 years ago
251
252
! strcmp ( bdrv_get_device_name ( drives_table [ i ]. bdrv ), device ))
bdrv_commit ( drives_table [ i ]. bdrv );
253
254
255
}
}
256
static void do_info ( Monitor * mon , const char * item )
257
{
258
259
const mon_cmd_t * cmd ;
void ( * handler )( Monitor * );
260
261
if ( ! item )
262
263
goto help ;
for ( cmd = info_cmds ; cmd -> name != NULL ; cmd ++ ) {
ths
authored
18 years ago
264
if ( compare_cmd ( item , cmd -> name ))
265
266
267
goto found ;
}
help :
268
help_cmd ( mon , "info" );
269
270
return ;
found :
271
handler = cmd -> handler ;
272
handler ( mon );
273
274
}
275
static void do_info_version ( Monitor * mon )
276
{
277
monitor_printf ( mon , "%s \n " , QEMU_VERSION QEMU_PKGVERSION );
278
279
}
280
static void do_info_name ( Monitor * mon )
ths
authored
18 years ago
281
282
{
if ( qemu_name )
283
monitor_printf ( mon , "%s \n " , qemu_name );
ths
authored
18 years ago
284
285
}
286
# if defined ( TARGET_I386 )
287
static void do_info_hpet ( Monitor * mon )
288
{
289
290
monitor_printf ( mon , "HPET is %s by QEMU \n " ,
( no_hpet ) ? "disabled" : "enabled" );
291
}
292
# endif
293
294
static void do_info_uuid ( Monitor * mon )
ths
authored
17 years ago
295
{
296
297
298
299
300
monitor_printf ( mon , UUID_FMT " \n " , qemu_uuid [ 0 ], qemu_uuid [ 1 ],
qemu_uuid [ 2 ], qemu_uuid [ 3 ], qemu_uuid [ 4 ], qemu_uuid [ 5 ],
qemu_uuid [ 6 ], qemu_uuid [ 7 ], qemu_uuid [ 8 ], qemu_uuid [ 9 ],
qemu_uuid [ 10 ], qemu_uuid [ 11 ], qemu_uuid [ 12 ], qemu_uuid [ 13 ],
qemu_uuid [ 14 ], qemu_uuid [ 15 ]);
ths
authored
17 years ago
301
302
}
303
/* get the current CPU defined by the user */
304
static int mon_set_cpu ( int cpu_index )
305
306
307
308
309
{
CPUState * env ;
for ( env = first_cpu ; env != NULL ; env = env -> next_cpu ) {
if ( env -> cpu_index == cpu_index ) {
310
cur_mon -> mon_cpu = env ;
311
312
313
314
315
316
return 0 ;
}
}
return - 1 ;
}
317
static CPUState * mon_get_cpu ( void )
318
{
319
if ( ! cur_mon -> mon_cpu ) {
320
321
mon_set_cpu ( 0 );
}
322
cpu_synchronize_state ( cur_mon -> mon_cpu , 0 );
323
return cur_mon -> mon_cpu ;
324
325
}
326
static void do_info_registers ( Monitor * mon )
327
{
328
329
330
331
CPUState * env ;
env = mon_get_cpu ();
if ( ! env )
return ;
332
# ifdef TARGET_I386
333
cpu_dump_state ( env , ( FILE * ) mon , monitor_fprintf ,
334
X86_DUMP_FPU );
335
# else
336
cpu_dump_state ( env , ( FILE * ) mon , monitor_fprintf ,
337
0 );
338
339
340
# endif
}
341
static void do_info_cpus ( Monitor * mon )
342
343
344
345
346
347
348
{
CPUState * env ;
/* just to set the default cpu if not already done */
mon_get_cpu ();
for ( env = first_cpu ; env != NULL ; env = env -> next_cpu ) {
349
cpu_synchronize_state ( env , 0 );
350
monitor_printf ( mon , "%c CPU #%d:" ,
351
( env == mon -> mon_cpu ) ? '*' : ' ' ,
352
env -> cpu_index );
353
# if defined ( TARGET_I386 )
354
355
monitor_printf ( mon , " pc=0x" TARGET_FMT_lx ,
env -> eip + env -> segs [ R_CS ]. base );
356
# elif defined ( TARGET_PPC )
357
monitor_printf ( mon , " nip=0x" TARGET_FMT_lx , env -> nip );
358
# elif defined ( TARGET_SPARC )
359
360
monitor_printf ( mon , " pc=0x" TARGET_FMT_lx " npc=0x" TARGET_FMT_lx ,
env -> pc , env -> npc );
ths
authored
18 years ago
361
# elif defined ( TARGET_MIPS )
362
monitor_printf ( mon , " PC=0x" TARGET_FMT_lx , env -> active_tc . PC );
363
# endif
ths
authored
18 years ago
364
if ( env -> halted )
365
366
monitor_printf ( mon , " (halted)" );
monitor_printf ( mon , " \n " );
367
368
369
}
}
370
static void do_cpu_set ( Monitor * mon , int index )
371
372
{
if ( mon_set_cpu ( index ) < 0 )
373
monitor_printf ( mon , "Invalid CPU index \n " );
374
375
}
376
static void do_info_jit ( Monitor * mon )
377
{
378
dump_exec_info (( FILE * ) mon , monitor_fprintf );
379
380
}
381
static void do_info_history ( Monitor * mon )
382
383
{
int i ;
384
const char * str ;
ths
authored
18 years ago
385
386
387
if ( ! mon -> rs )
return ;
388
389
i = 0 ;
for (;;) {
390
str = readline_get_history ( mon -> rs , i );
391
392
if ( ! str )
break ;
393
monitor_printf ( mon , "%d: '%s' \n " , i , str );
394
i ++ ;
395
396
397
}
}
398
399
# if defined ( TARGET_PPC )
/* XXX: not implemented in other targets */
400
static void do_info_cpu_stats ( Monitor * mon )
401
402
403
404
{
CPUState * env ;
env = mon_get_cpu ();
405
cpu_dump_statistics ( env , ( FILE * ) mon , & monitor_fprintf , 0 );
406
407
408
}
# endif
409
static void do_quit ( Monitor * mon )
410
411
412
413
{
exit ( 0 );
}
414
static int eject_device ( Monitor * mon , BlockDriverState * bs , int force )
415
416
417
418
{
if ( bdrv_is_inserted ( bs )) {
if ( ! force ) {
if ( ! bdrv_is_removable ( bs )) {
419
monitor_printf ( mon , "device is not removable \n " );
420
421
422
return - 1 ;
}
if ( bdrv_is_locked ( bs )) {
423
monitor_printf ( mon , "device is locked \n " );
424
425
426
427
428
429
430
431
return - 1 ;
}
}
bdrv_close ( bs );
}
return 0 ;
}
432
static void do_eject ( Monitor * mon , int force , const char * filename )
433
434
435
{
BlockDriverState * bs ;
436
bs = bdrv_find ( filename );
437
if ( ! bs ) {
438
monitor_printf ( mon , "device not found \n " );
439
440
return ;
}
441
eject_device ( mon , bs , force );
442
443
}
444
445
static void do_change_block ( Monitor * mon , const char * device ,
const char * filename , const char * fmt )
446
447
{
BlockDriverState * bs ;
448
BlockDriver * drv = NULL ;
449
450
bs = bdrv_find ( device );
451
if ( ! bs ) {
452
monitor_printf ( mon , "device not found \n " );
453
454
return ;
}
455
456
457
if ( fmt ) {
drv = bdrv_find_format ( fmt );
if ( ! drv ) {
458
monitor_printf ( mon , "invalid format %s \n " , fmt );
459
460
461
return ;
}
}
462
if ( eject_device ( mon , bs , 0 ) < 0 )
463
return ;
464
bdrv_open2 ( bs , filename , 0 , drv );
465
monitor_read_bdrv_key_start ( mon , bs , NULL , NULL );
466
467
}
468
469
static void change_vnc_password_cb ( Monitor * mon , const char * password ,
void * opaque )
470
471
{
if ( vnc_display_password ( NULL , password ) < 0 )
472
monitor_printf ( mon , "could not set VNC server password \n " );
473
474
monitor_read_command ( mon , 1 );
475
476
}
477
static void do_change_vnc ( Monitor * mon , const char * target , const char * arg )
ths
authored
18 years ago
478
{
ths
authored
18 years ago
479
if ( strcmp ( target , "passwd" ) == 0 ||
480
481
strcmp ( target , "password" ) == 0 ) {
if ( arg ) {
482
char password [ 9 ];
483
484
strncpy ( password , arg , sizeof ( password ));
password [ sizeof ( password ) - 1 ] = '\0' ;
485
change_vnc_password_cb ( mon , password , NULL );
486
} else {
487
monitor_read_password ( mon , change_vnc_password_cb , NULL );
488
}
ths
authored
18 years ago
489
} else {
490
if ( vnc_display_open ( NULL , target ) < 0 )
491
monitor_printf ( mon , "could not start VNC server on %s \n " , target );
ths
authored
18 years ago
492
}
ths
authored
18 years ago
493
494
}
495
496
static void do_change ( Monitor * mon , const char * device , const char * target ,
const char * arg )
ths
authored
18 years ago
497
498
{
if ( strcmp ( device , "vnc" ) == 0 ) {
499
do_change_vnc ( mon , target , arg );
ths
authored
18 years ago
500
} else {
501
do_change_block ( mon , device , target , arg );
ths
authored
18 years ago
502
503
504
}
}
505
static void do_screen_dump ( Monitor * mon , const char * filename )
506
{
507
vga_hw_screen_dump ( filename );
508
509
}
510
static void do_logfile ( Monitor * mon , const char * filename )
511
512
513
514
{
cpu_set_log_filename ( filename );
}
515
static void do_log ( Monitor * mon , const char * items )
516
517
{
int mask ;
ths
authored
18 years ago
518
519
if ( ! strcmp ( items , "none" )) {
520
521
mask = 0 ;
} else {
522
mask = cpu_str_to_log_mask ( items );
523
if ( ! mask ) {
524
help_cmd ( mon , "log" );
525
526
527
528
529
530
return ;
}
}
cpu_set_log ( mask );
}
531
532
533
534
535
536
537
538
539
540
541
static void do_singlestep ( Monitor * mon , const char * option )
{
if ( ! option || ! strcmp ( option , "on" )) {
singlestep = 1 ;
} else if ( ! strcmp ( option , "off" )) {
singlestep = 0 ;
} else {
monitor_printf ( mon , "unexpected option %s \n " , option );
}
}
542
static void do_stop ( Monitor * mon )
543
544
545
546
{
vm_stop ( EXCP_INTERRUPT );
}
547
static void encrypted_bdrv_it ( void * opaque , BlockDriverState * bs );
548
549
550
551
552
553
554
struct bdrv_iterate_context {
Monitor * mon ;
int err ;
};
static void do_cont ( Monitor * mon )
555
{
556
struct bdrv_iterate_context context = { mon , 0 };
557
558
bdrv_iterate ( encrypted_bdrv_it , & context );
559
/* only resume the vm if all keys are set and valid */
560
if ( ! context . err )
561
vm_start ();
562
563
}
564
565
static void bdrv_key_cb ( void * opaque , int err )
{
566
567
Monitor * mon = opaque ;
568
569
/* another key was set successfully, retry to continue */
if ( ! err )
570
do_cont ( mon );
571
572
573
574
}
static void encrypted_bdrv_it ( void * opaque , BlockDriverState * bs )
{
575
struct bdrv_iterate_context * context = opaque ;
576
577
578
579
580
if ( ! context -> err && bdrv_key_required ( bs )) {
context -> err = - EBUSY ;
monitor_read_bdrv_key_start ( context -> mon , bs , bdrv_key_cb ,
context -> mon );
581
582
583
}
}
584
# ifdef CONFIG_GDBSTUB
585
586
587
588
589
590
591
592
static void do_gdbserver ( Monitor * mon , const char * device )
{
if ( ! device )
device = "tcp::" DEFAULT_GDBSTUB_PORT ;
if ( gdbserver_start ( device ) < 0 ) {
monitor_printf ( mon , "Could not open gdbserver on device '%s' \n " ,
device );
} else if ( strcmp ( device , "none" ) == 0 ) {
593
monitor_printf ( mon , "Disabled gdbserver \n " );
594
} else {
595
596
monitor_printf ( mon , "Waiting for gdb connection on device '%s' \n " ,
device );
597
598
}
}
599
# endif
600
601
602
603
604
605
606
607
static void do_watchdog_action ( Monitor * mon , const char * action )
{
if ( select_watchdog_action ( action ) == - 1 ) {
monitor_printf ( mon , "Unknown watchdog action '%s' \n " , action );
}
}
608
static void monitor_printc ( Monitor * mon , int c )
609
{
610
monitor_printf ( mon , "'" );
611
612
switch ( c ) {
case '\'' :
613
monitor_printf ( mon , " \\ '" );
614
615
break ;
case '\\' :
616
monitor_printf ( mon , " \\\\ " );
617
618
break ;
case '\n' :
619
monitor_printf ( mon , " \\ n" );
620
621
break ;
case '\r' :
622
monitor_printf ( mon , " \\ r" );
623
624
625
break ;
default :
if ( c >= 32 && c <= 126 ) {
626
monitor_printf ( mon , "%c" , c );
627
} else {
628
monitor_printf ( mon , " \\ x%02x" , c );
629
630
631
}
break ;
}
632
monitor_printf ( mon , "'" );
633
634
}
635
static void memory_dump ( Monitor * mon , int count , int format , int wsize ,
636
target_phys_addr_t addr , int is_physical )
637
{
638
CPUState * env ;
639
640
641
642
643
644
645
int nb_per_line , l , line_size , i , max_digits , len ;
uint8_t buf [ 16 ];
uint64_t v ;
if ( format == 'i' ) {
int flags ;
flags = 0 ;
646
647
648
env = mon_get_cpu ();
if ( ! env && ! is_physical )
return ;
649
# ifdef TARGET_I386
650
if ( wsize == 2 ) {
651
flags = 1 ;
652
653
654
} else if ( wsize == 4 ) {
flags = 0 ;
} else {
655
/* as default we use the current CS size */
656
flags = 0 ;
657
658
if ( env ) {
# ifdef TARGET_X86_64
ths
authored
18 years ago
659
if (( env -> efer & MSR_EFER_LMA ) &&
660
661
662
663
664
665
666
( env -> segs [ R_CS ]. flags & DESC_L_MASK ))
flags = 2 ;
else
# endif
if ( ! ( env -> segs [ R_CS ]. flags & DESC_B_MASK ))
flags = 1 ;
}
667
668
}
# endif
669
monitor_disas ( mon , env , addr , count , is_physical , flags );
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
return ;
}
len = wsize * count ;
if ( wsize == 1 )
line_size = 8 ;
else
line_size = 16 ;
nb_per_line = line_size / wsize ;
max_digits = 0 ;
switch ( format ) {
case 'o' :
max_digits = ( wsize * 8 + 2 ) / 3 ;
break ;
default :
case 'x' :
max_digits = ( wsize * 8 ) / 4 ;
break ;
case 'u' :
case 'd' :
max_digits = ( wsize * 8 * 10 + 32 ) / 33 ;
break ;
case 'c' :
wsize = 1 ;
break ;
}
while ( len > 0 ) {
699
if ( is_physical )
700
monitor_printf ( mon , TARGET_FMT_plx ":" , addr );
701
else
702
monitor_printf ( mon , TARGET_FMT_lx ":" , ( target_ulong ) addr );
703
704
705
706
707
708
l = len ;
if ( l > line_size )
l = line_size ;
if ( is_physical ) {
cpu_physical_memory_rw ( addr , buf , l , 0 );
} else {
709
710
711
env = mon_get_cpu ();
if ( ! env )
break ;
712
if ( cpu_memory_rw_debug ( env , addr , buf , l , 0 ) < 0 ) {
713
monitor_printf ( mon , " Cannot access memory \n " );
714
715
break ;
}
716
}
ths
authored
18 years ago
717
i = 0 ;
718
719
720
721
722
723
724
725
726
727
while ( i < l ) {
switch ( wsize ) {
default :
case 1 :
v = ldub_raw ( buf + i );
break ;
case 2 :
v = lduw_raw ( buf + i );
break ;
case 4 :
728
v = ( uint32_t ) ldl_raw ( buf + i );
729
730
731
732
733
break ;
case 8 :
v = ldq_raw ( buf + i );
break ;
}
734
monitor_printf ( mon , " " );
735
736
switch ( format ) {
case 'o' :
737
monitor_printf ( mon , "%#*" PRIo64 , max_digits , v );
738
739
break ;
case 'x' :
740
monitor_printf ( mon , "0x%0*" PRIx64 , max_digits , v );
741
742
break ;
case 'u' :
743
monitor_printf ( mon , "%*" PRIu64 , max_digits , v );
744
745
break ;
case 'd' :
746
monitor_printf ( mon , "%*" PRId64 , max_digits , v );
747
748
break ;
case 'c' :
749
monitor_printc ( mon , v );
750
751
752
753
break ;
}
i += wsize ;
}
754
monitor_printf ( mon , " \n " );
755
756
757
758
759
addr += l ;
len -= l ;
}
}
760
761
762
763
764
765
# if TARGET_LONG_BITS == 64
# define GET_TLONG ( h , l ) ((( uint64_t )( h ) << 32 ) | ( l ))
# else
# define GET_TLONG ( h , l ) ( l )
# endif
766
static void do_memory_dump ( Monitor * mon , int count , int format , int size ,
767
uint32_t addrh , uint32_t addrl )
768
{
769
target_long addr = GET_TLONG ( addrh , addrl );
770
memory_dump ( mon , count , format , size , addr , 0 );
771
772
}
773
774
775
776
777
778
# if TARGET_PHYS_ADDR_BITS > 32
# define GET_TPHYSADDR ( h , l ) ((( uint64_t )( h ) << 32 ) | ( l ))
# else
# define GET_TPHYSADDR ( h , l ) ( l )
# endif
779
780
static void do_physical_memory_dump ( Monitor * mon , int count , int format ,
int size , uint32_t addrh , uint32_t addrl )
781
782
{
783
target_phys_addr_t addr = GET_TPHYSADDR ( addrh , addrl );
784
memory_dump ( mon , count , format , size , addr , 1 );
785
786
}
787
788
static void do_print ( Monitor * mon , int count , int format , int size ,
unsigned int valh , unsigned int vall )
789
{
790
791
target_phys_addr_t val = GET_TPHYSADDR ( valh , vall );
# if TARGET_PHYS_ADDR_BITS == 32
792
793
switch ( format ) {
case 'o' :
794
monitor_printf ( mon , "%#o" , val );
795
796
break ;
case 'x' :
797
monitor_printf ( mon , "%#x" , val );
798
799
break ;
case 'u' :
800
monitor_printf ( mon , "%u" , val );
801
802
803
break ;
default :
case 'd' :
804
monitor_printf ( mon , "%d" , val );
805
806
break ;
case 'c' :
807
monitor_printc ( mon , val );
808
809
break ;
}
810
811
812
# else
switch ( format ) {
case 'o' :
813
monitor_printf ( mon , "%#" PRIo64 , val );
814
815
break ;
case 'x' :
816
monitor_printf ( mon , "%#" PRIx64 , val );
817
818
break ;
case 'u' :
819
monitor_printf ( mon , "%" PRIu64 , val );
820
821
822
break ;
default :
case 'd' :
823
monitor_printf ( mon , "%" PRId64 , val );
824
825
break ;
case 'c' :
826
monitor_printc ( mon , val );
827
828
829
break ;
}
# endif
830
monitor_printf ( mon , " \n " );
831
832
}
833
static void do_memory_save ( Monitor * mon , unsigned int valh , unsigned int vall ,
834
835
836
837
838
839
840
841
842
843
844
845
846
847
uint32_t size , const char * filename )
{
FILE * f ;
target_long addr = GET_TLONG ( valh , vall );
uint32_t l ;
CPUState * env ;
uint8_t buf [ 1024 ];
env = mon_get_cpu ();
if ( ! env )
return ;
f = fopen ( filename , "wb" );
if ( ! f ) {
848
monitor_printf ( mon , "could not open '%s' \n " , filename );
849
850
851
852
853
854
855
856
857
858
859
860
861
862
return ;
}
while ( size != 0 ) {
l = sizeof ( buf );
if ( l > size )
l = size ;
cpu_memory_rw_debug ( env , addr , buf , l , 0 );
fwrite ( buf , 1 , l , f );
addr += l ;
size -= l ;
}
fclose ( f );
}
863
864
865
static void do_physical_memory_save ( Monitor * mon , unsigned int valh ,
unsigned int vall , uint32_t size ,
const char * filename )
866
867
868
869
{
FILE * f ;
uint32_t l ;
uint8_t buf [ 1024 ];
870
target_phys_addr_t addr = GET_TPHYSADDR ( valh , vall );
871
872
873
f = fopen ( filename , "wb" );
if ( ! f ) {
874
monitor_printf ( mon , "could not open '%s' \n " , filename );
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
return ;
}
while ( size != 0 ) {
l = sizeof ( buf );
if ( l > size )
l = size ;
cpu_physical_memory_rw ( addr , buf , l , 0 );
fwrite ( buf , 1 , l , f );
fflush ( f );
addr += l ;
size -= l ;
}
fclose ( f );
}
890
static void do_sum ( Monitor * mon , uint32_t start , uint32_t size )
891
892
893
894
895
896
897
898
899
900
901
902
{
uint32_t addr ;
uint8_t buf [ 1 ];
uint16_t sum ;
sum = 0 ;
for ( addr = start ; addr < ( start + size ); addr ++ ) {
cpu_physical_memory_rw ( addr , buf , 1 , 0 );
/* BSD sum algorithm ('sum' Unix command) */
sum = ( sum >> 1 ) | ( sum << 15 );
sum += buf [ 0 ];
}
903
monitor_printf ( mon , "%05d \n " , sum );
904
905
}
906
907
908
909
910
911
912
913
typedef struct {
int keycode ;
const char * name ;
} KeyDef ;
static const KeyDef key_defs [] = {
{ 0x2a , "shift" },
{ 0x36 , "shift_r" },
ths
authored
18 years ago
914
915
916
{ 0x38 , "alt" },
{ 0xb8 , "alt_r" },
ths
authored
17 years ago
917
918
{ 0x64 , "altgr" },
{ 0xe4 , "altgr_r" },
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
{ 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" },
936
937
{ 0x0c , "minus" },
{ 0x0d , "equal" },
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
{ 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" },
971
972
973
{ 0x33 , "comma" },
{ 0x34 , "dot" },
{ 0x35 , "slash" },
ths
authored
18 years ago
974
975
976
{ 0x37 , "asterisk" },
977
{ 0x39 , "spc" },
978
{ 0x3a , "caps_lock" },
979
980
981
982
983
984
985
986
987
988
{ 0x3b , "f1" },
{ 0x3c , "f2" },
{ 0x3d , "f3" },
{ 0x3e , "f4" },
{ 0x3f , "f5" },
{ 0x40 , "f6" },
{ 0x41 , "f7" },
{ 0x42 , "f8" },
{ 0x43 , "f9" },
{ 0x44 , "f10" },
989
{ 0x45 , "num_lock" },
990
991
{ 0x46 , "scroll_lock" },
992
993
{ 0xb5 , "kp_divide" },
{ 0x37 , "kp_multiply" },
ths
authored
18 years ago
994
{ 0x4a , "kp_subtract" },
995
996
997
{ 0x4e , "kp_add" },
{ 0x9c , "kp_enter" },
{ 0x53 , "kp_decimal" },
998
{ 0x54 , "sysrq" },
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
{ 0x52 , "kp_0" },
{ 0x4f , "kp_1" },
{ 0x50 , "kp_2" },
{ 0x51 , "kp_3" },
{ 0x4b , "kp_4" },
{ 0x4c , "kp_5" },
{ 0x4d , "kp_6" },
{ 0x47 , "kp_7" },
{ 0x48 , "kp_8" },
{ 0x49 , "kp_9" },
ths
authored
18 years ago
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
{ 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" },
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
# if defined ( TARGET_SPARC ) && ! defined ( TARGET_SPARC64 )
{ 0xf0 , "stop" },
{ 0xf1 , "again" },
{ 0xf2 , "props" },
{ 0xf3 , "undo" },
{ 0xf4 , "front" },
{ 0xf5 , "copy" },
{ 0xf6 , "open" },
{ 0xf7 , "paste" },
{ 0xf8 , "find" },
{ 0xf9 , "cut" },
{ 0xfa , "lf" },
{ 0xfb , "help" },
{ 0xfc , "meta_l" },
{ 0xfd , "meta_r" },
{ 0xfe , "compose" },
# endif
1047
1048
1049
1050
1051
1052
{ 0 , NULL },
};
static int get_keycode ( const char * key )
{
const KeyDef * p ;
1053
1054
char * endp ;
int ret ;
1055
1056
1057
1058
1059
for ( p = key_defs ; p -> name != NULL ; p ++ ) {
if ( ! strcmp ( key , p -> name ))
return p -> keycode ;
}
1060
1061
1062
1063
1064
if ( strstart ( key , "0x" , NULL )) {
ret = strtoul ( key , & endp , 0 );
if ( * endp == '\0' && ret >= 0x01 && ret <= 0xff )
return ret ;
}
1065
1066
1067
return - 1 ;
}
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
# define MAX_KEYCODES 16
static uint8_t keycodes [ MAX_KEYCODES ];
static int nb_pending_keycodes ;
static QEMUTimer * key_timer ;
static void release_keys ( void * opaque )
{
int keycode ;
while ( nb_pending_keycodes > 0 ) {
nb_pending_keycodes -- ;
keycode = keycodes [ nb_pending_keycodes ];
if ( keycode & 0x80 )
kbd_put_keycode ( 0xe0 );
kbd_put_keycode ( keycode | 0x80 );
}
}
1086
1087
static void do_sendkey ( Monitor * mon , const char * string , int has_hold_time ,
int hold_time )
1088
{
1089
1090
1091
1092
char keyname_buf [ 16 ];
char * separator ;
int keyname_len , keycode , i ;
1093
1094
1095
1096
1097
1098
1099
if ( nb_pending_keycodes > 0 ) {
qemu_del_timer ( key_timer );
release_keys ( NULL );
}
if ( ! has_hold_time )
hold_time = 100 ;
i = 0 ;
1100
1101
1102
1103
1104
1105
while ( 1 ) {
separator = strchr ( string , '-' );
keyname_len = separator ? separator - string : strlen ( string );
if ( keyname_len > 0 ) {
pstrcpy ( keyname_buf , sizeof ( keyname_buf ), string );
if ( keyname_len > sizeof ( keyname_buf ) - 1 ) {
1106
monitor_printf ( mon , "invalid key: '%s...' \n " , keyname_buf );
1107
return ;
1108
}
1109
if ( i == MAX_KEYCODES ) {
1110
monitor_printf ( mon , "too many keys \n " );
1111
1112
1113
1114
1115
return ;
}
keyname_buf [ keyname_len ] = 0 ;
keycode = get_keycode ( keyname_buf );
if ( keycode < 0 ) {
1116
monitor_printf ( mon , "unknown key: '%s' \n " , keyname_buf );
1117
1118
return ;
}
1119
keycodes [ i ++ ] = keycode ;
1120
}
1121
if ( ! separator )
1122
break ;
1123
string = separator + 1 ;
1124
}
1125
nb_pending_keycodes = i ;
1126
/* key down events */
1127
for ( i = 0 ; i < nb_pending_keycodes ; i ++ ) {
1128
1129
1130
1131
1132
keycode = keycodes [ i ];
if ( keycode & 0x80 )
kbd_put_keycode ( 0xe0 );
kbd_put_keycode ( keycode & 0x7f );
}
1133
/* delayed key up events */
1134
1135
qemu_mod_timer ( key_timer , qemu_get_clock ( vm_clock ) +
muldiv64 ( ticks_per_sec , hold_time , 1000 ));
1136
1137
}
1138
1139
static int mouse_button_state ;
1140
static void do_mouse_move ( Monitor * mon , const char * dx_str , const char * dy_str ,
1141
1142
1143
1144
1145
1146
const char * dz_str )
{
int dx , dy , dz ;
dx = strtol ( dx_str , NULL , 0 );
dy = strtol ( dy_str , NULL , 0 );
dz = 0 ;
ths
authored
18 years ago
1147
if ( dz_str )
1148
1149
1150
1151
dz = strtol ( dz_str , NULL , 0 );
kbd_mouse_event ( dx , dy , dz , mouse_button_state );
}
1152
static void do_mouse_button ( Monitor * mon , int button_state )
1153
1154
1155
1156
1157
{
mouse_button_state = button_state ;
kbd_mouse_event ( 0 , 0 , 0 , mouse_button_state );
}
1158
1159
static void do_ioport_read ( Monitor * mon , int count , int format , int size ,
int addr , int has_index , int index )
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
{
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 ;
}
1185
1186
monitor_printf ( mon , "port%c[0x%04x] = %#0*x \n " ,
suffix , addr , size * 2 , val );
1187
}
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
/* boot_set handler */
static QEMUBootSetHandler * qemu_boot_set_handler = NULL ;
static void * boot_opaque ;
void qemu_register_boot_set ( QEMUBootSetHandler * func , void * opaque )
{
qemu_boot_set_handler = func ;
boot_opaque = opaque ;
}
1199
static void do_boot_set ( Monitor * mon , const char * bootdevice )
1200
1201
1202
1203
{
int res ;
if ( qemu_boot_set_handler ) {
1204
res = qemu_boot_set_handler ( boot_opaque , bootdevice );
1205
if ( res == 0 )
1206
1207
monitor_printf ( mon , "boot device list now set to %s \n " ,
bootdevice );
1208
else
1209
1210
monitor_printf ( mon , "setting boot device list failed with "
"error %i \n " , res );
1211
} else {
1212
1213
monitor_printf ( mon , "no function defined to set boot device list for "
"this architecture \n " );
1214
1215
1216
}
}
1217
static void do_system_reset ( Monitor * mon )
1218
1219
1220
1221
{
qemu_system_reset_request ();
}
1222
static void do_system_powerdown ( Monitor * mon )
1223
1224
1225
1226
{
qemu_system_powerdown_request ();
}
1227
# if defined ( TARGET_I386 )
1228
static void print_pte ( Monitor * mon , uint32_t addr , uint32_t pte , uint32_t mask )
1229
{
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
monitor_printf ( mon , "%08x: %08x %c%c%c%c%c%c%c%c \n " ,
addr ,
pte & mask ,
pte & PG_GLOBAL_MASK ? 'G' : '-' ,
pte & PG_PSE_MASK ? 'P' : '-' ,
pte & PG_DIRTY_MASK ? 'D' : '-' ,
pte & PG_ACCESSED_MASK ? 'A' : '-' ,
pte & PG_PCD_MASK ? 'C' : '-' ,
pte & PG_PWT_MASK ? 'T' : '-' ,
pte & PG_USER_MASK ? 'U' : '-' ,
pte & PG_RW_MASK ? 'W' : '-' );
1241
1242
}
1243
static void tlb_info ( Monitor * mon )
1244
{
1245
CPUState * env ;
1246
1247
1248
int l1 , l2 ;
uint32_t pgd , pde , pte ;
1249
1250
1251
1252
env = mon_get_cpu ();
if ( ! env )
return ;
1253
if ( ! ( env -> cr [ 0 ] & CR0_PG_MASK )) {
1254
monitor_printf ( mon , "PG disabled \n " );
1255
1256
1257
1258
1259
1260
1261
1262
return ;
}
pgd = env -> cr [ 3 ] & ~ 0xfff ;
for ( l1 = 0 ; l1 < 1024 ; l1 ++ ) {
cpu_physical_memory_read ( pgd + l1 * 4 , ( uint8_t * ) & pde , 4 );
pde = le32_to_cpu ( pde );
if ( pde & PG_PRESENT_MASK ) {
if (( pde & PG_PSE_MASK ) && ( env -> cr [ 4 ] & CR4_PSE_MASK )) {
1263
print_pte ( mon , ( l1 << 22 ), pde , ~ (( 1 << 20 ) - 1 ));
1264
1265
} else {
for ( l2 = 0 ; l2 < 1024 ; l2 ++ ) {
ths
authored
18 years ago
1266
cpu_physical_memory_read (( pde & ~ 0xfff ) + l2 * 4 ,
1267
1268
1269
( uint8_t * ) & pte , 4 );
pte = le32_to_cpu ( pte );
if ( pte & PG_PRESENT_MASK ) {
1270
print_pte ( mon , ( l1 << 22 ) + ( l2 << 12 ),
ths
authored
18 years ago
1271
pte & ~ PG_PSE_MASK ,
1272
1273
1274
1275
1276
1277
1278
1279
~ 0xfff );
}
}
}
}
}
}
1280
static void mem_print ( Monitor * mon , uint32_t * pstart , int * plast_prot ,
1281
1282
uint32_t end , int prot )
{
1283
1284
1285
int prot1 ;
prot1 = * plast_prot ;
if ( prot != prot1 ) {
1286
if ( * pstart != - 1 ) {
1287
1288
1289
1290
1291
monitor_printf ( mon , "%08x-%08x %08x %c%c%c \n " ,
* pstart , end , end - * pstart ,
prot1 & PG_USER_MASK ? 'u' : '-' ,
'r' ,
prot1 & PG_RW_MASK ? 'w' : '-' );
1292
1293
1294
1295
1296
1297
1298
1299
1300
}
if ( prot != 0 )
* pstart = end ;
else
* pstart = - 1 ;
* plast_prot = prot ;
}
}
1301
static void mem_info ( Monitor * mon )
1302
{
1303
CPUState * env ;
1304
1305
1306
int l1 , l2 , prot , last_prot ;
uint32_t pgd , pde , pte , start , end ;
1307
1308
1309
1310
env = mon_get_cpu ();
if ( ! env )
return ;
1311
if ( ! ( env -> cr [ 0 ] & CR0_PG_MASK )) {
1312
monitor_printf ( mon , "PG disabled \n " );
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
return ;
}
pgd = env -> cr [ 3 ] & ~ 0xfff ;
last_prot = 0 ;
start = - 1 ;
for ( l1 = 0 ; l1 < 1024 ; l1 ++ ) {
cpu_physical_memory_read ( pgd + l1 * 4 , ( uint8_t * ) & pde , 4 );
pde = le32_to_cpu ( pde );
end = l1 << 22 ;
if ( pde & PG_PRESENT_MASK ) {
if (( pde & PG_PSE_MASK ) && ( env -> cr [ 4 ] & CR4_PSE_MASK )) {
prot = pde & ( PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK );
1325
mem_print ( mon , & start , & last_prot , end , prot );
1326
1327
} else {
for ( l2 = 0 ; l2 < 1024 ; l2 ++ ) {
ths
authored
18 years ago
1328
cpu_physical_memory_read (( pde & ~ 0xfff ) + l2 * 4 ,
1329
1330
1331
1332
1333
1334
1335
1336
( uint8_t * ) & pte , 4 );
pte = le32_to_cpu ( pte );
end = ( l1 << 22 ) + ( l2 << 12 );
if ( pte & PG_PRESENT_MASK ) {
prot = pte & ( PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK );
} else {
prot = 0 ;
}
1337
mem_print ( mon , & start , & last_prot , end , prot );
1338
1339
1340
1341
}
}
} else {
prot = 0 ;
1342
mem_print ( mon , & start , & last_prot , end , prot );
1343
1344
1345
1346
1347
}
}
}
# endif
1348
1349
# if defined ( TARGET_SH4 )
1350
static void print_tlb ( Monitor * mon , int idx , tlb_t * tlb )
1351
{
1352
1353
1354
1355
1356
1357
1358
1359
monitor_printf ( mon , " tlb%i: \t "
"asid=%hhu vpn=%x \t ppn=%x \t sz=%hhu size=%u \t "
"v=%hhu shared=%hhu cached=%hhu prot=%hhu "
"dirty=%hhu writethrough=%hhu \n " ,
idx ,
tlb -> asid , tlb -> vpn , tlb -> ppn , tlb -> sz , tlb -> size ,
tlb -> v , tlb -> sh , tlb -> c , tlb -> pr ,
tlb -> d , tlb -> wt );
1360
1361
}
1362
static void tlb_info ( Monitor * mon )
1363
1364
1365
1366
{
CPUState * env = mon_get_cpu ();
int i ;
1367
monitor_printf ( mon , "ITLB: \n " );
1368
for ( i = 0 ; i < ITLB_SIZE ; i ++ )
1369
1370
print_tlb ( mon , i , & env -> itlb [ i ]);
monitor_printf ( mon , "UTLB: \n " );
1371
for ( i = 0 ; i < UTLB_SIZE ; i ++ )
1372
print_tlb ( mon , i , & env -> utlb [ i ]);
1373
1374
1375
1376
}
# endif
1377
static void do_info_kqemu ( Monitor * mon )
1378
{
1379
# ifdef CONFIG_KQEMU
1380
CPUState * env ;
1381
1382
int val ;
val = 0 ;
1383
1384
env = mon_get_cpu ();
if ( ! env ) {
1385
monitor_printf ( mon , "No cpu initialized yet" );
1386
1387
1388
return ;
}
val = env -> kqemu_enabled ;
1389
monitor_printf ( mon , "kqemu support: " );
1390
1391
1392
switch ( val ) {
default :
case 0 :
1393
monitor_printf ( mon , "disabled \n " );
1394
1395
break ;
case 1 :
1396
monitor_printf ( mon , "enabled for user code \n " );
1397
1398
break ;
case 2 :
1399
monitor_printf ( mon , "enabled for user and kernel code \n " );
1400
1401
break ;
}
1402
# else
1403
monitor_printf ( mon , "kqemu support: not compiled \n " );
1404
# endif
ths
authored
18 years ago
1405
}
1406
1407
static void do_info_kvm ( Monitor * mon )
1408
1409
{
# ifdef CONFIG_KVM
1410
monitor_printf ( mon , "kvm support: " );
1411
if ( kvm_enabled ())
1412
monitor_printf ( mon , "enabled \n " );
1413
else
1414
monitor_printf ( mon , "disabled \n " );
1415
# else
1416
monitor_printf ( mon , "kvm support: not compiled \n " );
1417
1418
1419
# endif
}
1420
1421
static void do_info_numa ( Monitor * mon )
{
1422
int i ;
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
CPUState * env ;
monitor_printf ( mon , "%d nodes \n " , nb_numa_nodes );
for ( i = 0 ; i < nb_numa_nodes ; i ++ ) {
monitor_printf ( mon , "node %d cpus:" , i );
for ( env = first_cpu ; env != NULL ; env = env -> next_cpu ) {
if ( env -> numa_node == i ) {
monitor_printf ( mon , " %d" , env -> cpu_index );
}
}
monitor_printf ( mon , " \n " );
monitor_printf ( mon , "node %d size: %" PRId64 " MB \n " , i ,
node_mem [ i ] >> 20 );
}
}
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
# ifdef CONFIG_PROFILER
int64_t kqemu_time ;
int64_t qemu_time ;
int64_t kqemu_exec_count ;
int64_t dev_time ;
int64_t kqemu_ret_int_count ;
int64_t kqemu_ret_excp_count ;
int64_t kqemu_ret_intr_count ;
1449
static void do_info_profile ( Monitor * mon )
1450
1451
1452
1453
1454
{
int64_t total ;
total = qemu_time ;
if ( total == 0 )
total = 1 ;
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
monitor_printf ( mon , "async time %" PRId64 " (%0.3f) \n " ,
dev_time , dev_time / ( double ) ticks_per_sec );
monitor_printf ( mon , "qemu time %" PRId64 " (%0.3f) \n " ,
qemu_time , qemu_time / ( double ) ticks_per_sec );
monitor_printf ( mon , "kqemu time %" PRId64 " (%0.3f %0.1f%%) count=%"
PRId64 " int=%" PRId64 " excp=%" PRId64 " intr=%"
PRId64 " \n " ,
kqemu_time , kqemu_time / ( double ) ticks_per_sec ,
kqemu_time / ( double ) total * 100 . 0 ,
kqemu_exec_count ,
kqemu_ret_int_count ,
kqemu_ret_excp_count ,
kqemu_ret_intr_count );
1468
1469
1470
1471
1472
1473
1474
qemu_time = 0 ;
kqemu_time = 0 ;
kqemu_exec_count = 0 ;
dev_time = 0 ;
kqemu_ret_int_count = 0 ;
kqemu_ret_excp_count = 0 ;
kqemu_ret_intr_count = 0 ;
1475
# ifdef CONFIG_KQEMU
1476
1477
1478
1479
kqemu_record_dump ();
# endif
}
# else
1480
static void do_info_profile ( Monitor * mon )
1481
{
1482
monitor_printf ( mon , "Internal profiler not compiled \n " );
1483
1484
1485
}
# endif
1486
1487
1488
/* Capture support */
static LIST_HEAD ( capture_list_head , CaptureState ) capture_head ;
1489
static void do_info_capture ( Monitor * mon )
1490
1491
1492
1493
1494
{
int i ;
CaptureState * s ;
for ( s = capture_head . lh_first , i = 0 ; s ; s = s -> entries . le_next , ++ i ) {
1495
monitor_printf ( mon , "[%d]: " , i );
1496
1497
1498
1499
s -> ops . info ( s -> opaque );
}
}
1500
static void do_stop_capture ( Monitor * mon , int n )
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
{
int i ;
CaptureState * s ;
for ( s = capture_head . lh_first , i = 0 ; s ; s = s -> entries . le_next , ++ i ) {
if ( i == n ) {
s -> ops . destroy ( s -> opaque );
LIST_REMOVE ( s , entries );
qemu_free ( s );
return ;
}
}
}
# ifdef HAS_AUDIO
1516
1517
1518
1519
static void do_wav_capture ( Monitor * mon , const char * path ,
int has_freq , int freq ,
int has_bits , int bits ,
int has_channels , int nchannels )
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
{
CaptureState * s ;
s = qemu_mallocz ( sizeof ( * s ));
freq = has_freq ? freq : 44100 ;
bits = has_bits ? bits : 16 ;
nchannels = has_channels ? nchannels : 2 ;
if ( wav_start_capture ( s , path , freq , bits , nchannels )) {
1530
monitor_printf ( mon , "Faied to add wave capture \n " );
1531
1532
1533
1534
1535
1536
qemu_free ( s );
}
LIST_INSERT_HEAD ( & capture_head , s , entries );
}
# endif
1537
# if defined ( TARGET_I386 )
1538
static void do_inject_nmi ( Monitor * mon , int cpu_index )
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
{
CPUState * env ;
for ( env = first_cpu ; env != NULL ; env = env -> next_cpu )
if ( env -> cpu_index == cpu_index ) {
cpu_interrupt ( env , CPU_INTERRUPT_NMI );
break ;
}
}
# endif
1550
static void do_info_status ( Monitor * mon )
1551
{
1552
1553
1554
1555
1556
1557
1558
if ( vm_running ) {
if ( singlestep ) {
monitor_printf ( mon , "VM status: running (single step mode) \n " );
} else {
monitor_printf ( mon , "VM status: running \n " );
}
} else
1559
monitor_printf ( mon , "VM status: paused \n " );
1560
1561
1562
}
1563
static void do_balloon ( Monitor * mon , int value )
1564
1565
1566
1567
1568
{
ram_addr_t target = value ;
qemu_balloon ( target << 20 );
}
1569
static void do_info_balloon ( Monitor * mon )
1570
1571
1572
1573
{
ram_addr_t actual ;
actual = qemu_balloon_status ();
1574
if ( kvm_enabled () && ! kvm_has_sync_mmu ())
1575
1576
monitor_printf ( mon , "Using KVM without synchronous MMU, "
"ballooning disabled \n " );
1577
else if ( actual == 0 )
1578
monitor_printf ( mon , "Ballooning not activated in VM \n " );
1579
else
1580
monitor_printf ( mon , "balloon: actual=%d \n " , ( int )( actual >> 20 ));
1581
1582
}
1583
1584
static void do_acl ( Monitor * mon ,
const char * command ,
1585
1586
1587
1588
const char * aclname ,
const char * match ,
int has_index ,
int index )
1589
1590
1591
1592
1593
{
qemu_acl * acl ;
acl = qemu_acl_find ( aclname );
if ( ! acl ) {
1594
1595
monitor_printf ( mon , "acl: unknown list '%s' \n " , aclname );
return ;
1596
1597
1598
}
if ( strcmp ( command , "show" ) == 0 ) {
1599
1600
1601
int i = 0 ;
qemu_acl_entry * entry ;
monitor_printf ( mon , "policy: %s \n " ,
1602
acl -> defaultDeny ? "deny" : "allow" );
1603
1604
1605
TAILQ_FOREACH ( entry , & acl -> entries , next ) {
i ++ ;
monitor_printf ( mon , "%d: %s %s \n " , i ,
1606
1607
entry -> deny ? "deny" : "allow" ,
entry -> match );
1608
}
1609
} else if ( strcmp ( command , "reset" ) == 0 ) {
1610
1611
qemu_acl_reset ( acl );
monitor_printf ( mon , "acl: removed all rules \n " );
1612
} else if ( strcmp ( command , "policy" ) == 0 ) {
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
if ( ! match ) {
monitor_printf ( mon , "acl: missing policy parameter \n " );
return ;
}
if ( strcmp ( match , "allow" ) == 0 ) {
acl -> defaultDeny = 0 ;
monitor_printf ( mon , "acl: policy set to 'allow' \n " );
} else if ( strcmp ( match , "deny" ) == 0 ) {
acl -> defaultDeny = 1 ;
monitor_printf ( mon , "acl: policy set to 'deny' \n " );
} else {
monitor_printf ( mon , "acl: unknown policy '%s', expected 'deny' or 'allow' \n " , match );
}
1627
} else if (( strcmp ( command , "allow" ) == 0 ) ||
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
( strcmp ( command , "deny" ) == 0 )) {
int deny = strcmp ( command , "deny" ) == 0 ? 1 : 0 ;
int ret ;
if ( ! match ) {
monitor_printf ( mon , "acl: missing match parameter \n " );
return ;
}
if ( has_index )
ret = qemu_acl_insert ( acl , deny , match , index );
else
ret = qemu_acl_append ( acl , deny , match );
if ( ret < 0 )
monitor_printf ( mon , "acl: unable to add acl entry \n " );
else
monitor_printf ( mon , "acl: added rule at position %d \n " , ret );
1645
} else if ( strcmp ( command , "remove" ) == 0 ) {
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
int ret ;
if ( ! match ) {
monitor_printf ( mon , "acl: missing match parameter \n " );
return ;
}
ret = qemu_acl_remove ( acl , match );
if ( ret < 0 )
monitor_printf ( mon , "acl: no matching acl entry \n " );
else
monitor_printf ( mon , "acl: removed rule at position %d \n " , ret );
1658
} else {
1659
monitor_printf ( mon , "acl: unknown command '%s' \n " , command );
1660
1661
1662
}
}
1663
/* Please update qemu-doc.texi when adding or changing commands */
1664
1665
static const mon_cmd_t mon_cmds [] = {
{ "help|?" , "s?" , help_cmd ,
1666
"[cmd]" , "show the help" },
ths
authored
18 years ago
1667
{ "commit" , "s" , do_commit ,
1668
"device|all" , "commit changes to the disk images (if -snapshot is used) or backing files" },
1669
{ "info" , "s?" , do_info ,
1670
"[subcommand]" , "show various information about the system state" },
1671
{ "q|quit" , "" , do_quit ,
1672
"" , "quit the emulator" },
1673
{ "eject" , "-fB" , do_eject ,
ths
authored
18 years ago
1674
"[-f] device" , "eject a removable medium (use -f to force it)" },
1675
1676
{ "change" , "BFs?" , do_change ,
"device filename [format]" , "change a removable medium, optional format" },
ths
authored
18 years ago
1677
{ "screendump" , "F" , do_screen_dump ,
1678
"filename" , "save screen into PPM image 'filename'" },
1679
{ "logfile" , "F" , do_logfile ,
1680
"filename" , "output logs to 'filename'" },
1681
{ "log" , "s" , do_log ,
ths
authored
18 years ago
1682
"item1[,...]" , "activate logging of the specified items to '/tmp/qemu.log'" },
1683
{ "savevm" , "s?" , do_savevm ,
1684
"[tag|id]" , "save a VM snapshot. If no tag or id are provided, a new snapshot is created" },
1685
{ "loadvm" , "s" , do_loadvm ,
ths
authored
18 years ago
1686
"tag|id" , "restore a VM snapshot from its tag or id" },
1687
{ "delvm" , "s" , do_delvm ,
ths
authored
18 years ago
1688
"tag|id" , "delete a VM snapshot from its tag or id" },
1689
1690
{ "singlestep" , "s?" , do_singlestep ,
"[on|off]" , "run emulation in singlestep mode or switch to normal mode" , },
ths
authored
18 years ago
1691
{ "stop" , "" , do_stop ,
1692
"" , "stop emulation" , },
ths
authored
18 years ago
1693
{ "c|cont" , "" , do_cont ,
1694
"" , "resume emulation" , },
1695
# ifdef CONFIG_GDBSTUB
ths
authored
18 years ago
1696
{ "gdbserver" , "s?" , do_gdbserver ,
1697
"[device]" , "start gdbserver on given device (default 'tcp::1234'), stop with 'none'" , },
1698
# endif
ths
authored
18 years ago
1699
{ "x" , "/l" , do_memory_dump ,
1700
"/fmt addr" , "virtual memory dump starting at 'addr'" , },
ths
authored
18 years ago
1701
{ "xp" , "/l" , do_physical_memory_dump ,
1702
"/fmt addr" , "physical memory dump starting at 'addr'" , },
ths
authored
18 years ago
1703
{ "p|print" , "/l" , do_print ,
1704
"/fmt expr" , "print expression value (use $reg for CPU register access)" , },
ths
authored
18 years ago
1705
{ "i" , "/ii." , do_ioport_read ,
1706
1707
"/fmt addr" , "I/O port read" },
1708
1709
{ "sendkey" , "si?" , do_sendkey ,
"keys [hold_ms]" , "send keys to the VM (e.g. 'sendkey ctrl-alt-f1', default hold time=100 ms)" },
ths
authored
18 years ago
1710
{ "system_reset" , "" , do_system_reset ,
1711
"" , "reset the system" },
ths
authored
18 years ago
1712
{ "system_powerdown" , "" , do_system_powerdown ,
1713
"" , "send system power down event" },
ths
authored
18 years ago
1714
{ "sum" , "ii" , do_sum ,
1715
"addr size" , "compute the checksum of a memory region" },
1716
1717
1718
1719
{ "usb_add" , "s" , do_usb_add ,
"device" , "add USB device (e.g. 'host:bus.addr' or 'host:vendor_id:product_id')" },
{ "usb_del" , "s" , do_usb_del ,
"device" , "remove USB device 'bus.addr'" },
ths
authored
18 years ago
1720
{ "cpu" , "i" , do_cpu_set ,
1721
"index" , "set the default CPU" },
ths
authored
18 years ago
1722
{ "mouse_move" , "sss?" , do_mouse_move ,
1723
"dx dy [dz]" , "send mouse move events" },
ths
authored
18 years ago
1724
{ "mouse_button" , "i" , do_mouse_button ,
1725
"state" , "change mouse button state (1=L, 2=M, 4=R)" },
ths
authored
18 years ago
1726
1727
{ "mouse_set" , "i" , do_mouse_set ,
"index" , "set which mouse device receives events" },
1728
1729
# ifdef HAS_AUDIO
{ "wavcapture" , "si?i?i?" , do_wav_capture ,
1730
"path [frequency [bits [channels]]]" ,
1731
1732
"capture audio to a wave file (default frequency=44100 bits=16 channels=2)" },
# endif
1733
1734
{ "stopcapture" , "i" , do_stop_capture ,
"capture index" , "stop capture" },
ths
authored
18 years ago
1735
{ "memsave" , "lis" , do_memory_save ,
1736
"addr size file" , "save to disk virtual memory dump starting at 'addr' of size 'size'" , },
1737
1738
{ "pmemsave" , "lis" , do_physical_memory_save ,
"addr size file" , "save to disk physical memory dump starting at 'addr' of size 'size'" , },
1739
1740
{ "boot_set" , "s" , do_boot_set ,
"bootdevice" , "define new values for the boot device list" },
1741
1742
1743
1744
# if defined ( TARGET_I386 )
{ "nmi" , "i" , do_inject_nmi ,
"cpu" , "inject an NMI on the given CPU" , },
# endif
1745
1746
1747
1748
1749
1750
{ "migrate" , "-ds" , do_migrate ,
"[-d] uri" , "migrate to URI (using -d to not wait for completion)" },
{ "migrate_cancel" , "" , do_migrate_cancel ,
"" , "cancel the current VM migration" },
{ "migrate_set_speed" , "s" , do_migrate_set_speed ,
"value" , "set maximum speed (in bytes) for migrations" },
1751
1752
1753
1754
1755
1756
1757
1758
1759
# if defined ( TARGET_I386 )
{ "drive_add" , "ss" , drive_hot_add , "pci_addr=[[<domain>:]<bus>:]<slot> \n "
"[file=file][,if=type][,bus=n] \n "
"[,unit=m][,media=d][index=i] \n "
"[,cyls=c,heads=h,secs=s[,trans=t]] \n "
"[snapshot=on|off][,cache=on|off]" ,
"add drive to PCI storage controller" },
{ "pci_add" , "sss" , pci_device_hot_add , "pci_addr=auto|[[<domain>:]<bus>:]<slot> nic|storage [[vlan=n][,macaddr=addr][,model=type]] [file=file][,if=type][,bus=nr]..." , "hot-add PCI device" },
{ "pci_del" , "s" , pci_device_hot_remove , "pci_addr=[[<domain>:]<bus>:]<slot>" , "hot remove PCI device" },
1760
# endif
1761
1762
{ "host_net_add" , "ss?" , net_host_device_add ,
"tap|user|socket|vde|dump [options]" , "add host VLAN client" },
1763
1764
{ "host_net_remove" , "is" , net_host_device_remove ,
"vlan_id name" , "remove host VLAN client" },
1765
1766
1767
1768
# ifdef CONFIG_SLIRP
{ "host_net_redir" , "s" , net_slirp_redir ,
"[tcp|udp]:host-port:[guest-host]:guest-port" , "redirect TCP or UDP connections from host to guest (requires -net user)" },
# endif
1769
1770
{ "balloon" , "i" , do_balloon ,
"target" , "request VM to change it's memory allocation (in MB)" },
1771
{ "set_link" , "ss" , do_set_link ,
1772
"name up|down" , "change the link status of a network adapter" },
1773
1774
{ "watchdog_action" , "s" , do_watchdog_action ,
"[reset|shutdown|poweroff|pause|debug|none]" , "change watchdog action" },
1775
{ "acl" , "sss?i?" , do_acl , "<command> <aclname> [<match> [<index>]] \n " ,
1776
1777
1778
1779
1780
"acl show vnc.username \n "
"acl policy vnc.username deny \n "
"acl allow vnc.username fred \n "
"acl deny vnc.username bob \n "
"acl reset vnc.username \n " },
ths
authored
18 years ago
1781
{ NULL , NULL , },
1782
1783
};
1784
/* Please update qemu-doc.texi when adding or changing commands */
1785
static const mon_cmd_t info_cmds [] = {
1786
{ "version" , "" , do_info_version ,
1787
"" , "show the version of QEMU" },
1788
{ "network" , "" , do_info_network ,
1789
"" , "show the network state" },
1790
1791
{ "chardev" , "" , qemu_chr_info ,
"" , "show the character devices" },
1792
{ "block" , "" , bdrv_info ,
1793
"" , "show the block devices" },
1794
{ "blockstats" , "" , bdrv_info_stats ,
ths
authored
17 years ago
1795
"" , "show block device statistics" },
1796
1797
{ "registers" , "" , do_info_registers ,
"" , "show the cpu registers" },
1798
1799
{ "cpus" , "" , do_info_cpus ,
"" , "show infos for each CPU" },
1800
1801
{ "history" , "" , do_info_history ,
"" , "show the command line history" , },
1802
1803
{ "irq" , "" , irq_info ,
"" , "show the interrupts statistics (if available)" , },
1804
1805
{ "pic" , "" , pic_info ,
"" , "show i8259 (PIC) state" , },
1806
1807
{ "pci" , "" , pci_info ,
"" , "show PCI info" , },
1808
# if defined ( TARGET_I386 ) || defined ( TARGET_SH4 )
1809
1810
{ "tlb" , "" , tlb_info ,
"" , "show virtual to physical memory mappings" , },
1811
1812
# endif
# if defined ( TARGET_I386 )
1813
1814
{ "mem" , "" , mem_info ,
"" , "show the active virtual memory mappings" , },
1815
1816
{ "hpet" , "" , do_info_hpet ,
"" , "show state of HPET" , },
1817
# endif
1818
1819
{ "jit" , "" , do_info_jit ,
"" , "show dynamic compiler info" , },
1820
{ "kqemu" , "" , do_info_kqemu ,
1821
"" , "show KQEMU information" , },
1822
{ "kvm" , "" , do_info_kvm ,
1823
"" , "show KVM information" , },
1824
1825
{ "numa" , "" , do_info_numa ,
"" , "show NUMA information" , },
1826
1827
1828
1829
{ "usb" , "" , usb_info ,
"" , "show guest USB devices" , },
{ "usbhost" , "" , usb_host_info ,
"" , "show host USB devices" , },
1830
1831
{ "profile" , "" , do_info_profile ,
"" , "show profiling information" , },
1832
{ "capture" , "" , do_info_capture ,
1833
"" , "show capture information" },
1834
{ "snapshots" , "" , do_info_snapshots ,
1835
"" , "show the currently saved VM snapshots" },
1836
1837
{ "status" , "" , do_info_status ,
"" , "show the current VM status (running|paused)" },
1838
1839
{ "pcmcia" , "" , pcmcia_info ,
"" , "show guest PCMCIA status" },
ths
authored
18 years ago
1840
1841
{ "mice" , "" , do_info_mice ,
"" , "show which guest mouse is receiving events" },
1842
1843
{ "vnc" , "" , do_info_vnc ,
"" , "show the vnc server status" },
ths
authored
18 years ago
1844
1845
{ "name" , "" , do_info_name ,
"" , "show the current VM name" },
1846
1847
{ "uuid" , "" , do_info_uuid ,
"" , "show the current VM UUID" },
1848
1849
1850
1851
# if defined ( TARGET_PPC )
{ "cpustats" , "" , do_info_cpu_stats ,
"" , "show CPU statistics" , },
# endif
1852
1853
1854
1855
# if defined ( CONFIG_SLIRP )
{ "slirp" , "" , do_info_slirp ,
"" , "show SLIRP statistics" , },
# endif
1856
{ "migrate" , "" , do_info_migrate , "" , "show migration status" },
1857
1858
{ "balloon" , "" , do_info_balloon ,
"" , "show balloon information" },
1859
1860
1861
{ NULL , NULL , },
};
1862
1863
1864
1865
1866
/*******************************************************************/
static const char * pch ;
static jmp_buf expr_env ;
1867
1868
1869
# define MD_TLONG 0
# define MD_I32 1
1870
1871
1872
typedef struct MonitorDef {
const char * name ;
int offset ;
1873
target_long ( * get_value )( const struct MonitorDef * md , int val );
1874
int type ;
1875
1876
} MonitorDef ;
1877
# if defined ( TARGET_I386 )
1878
static target_long monitor_get_pc ( const struct MonitorDef * md , int val )
1879
{
1880
1881
1882
1883
CPUState * env = mon_get_cpu ();
if ( ! env )
return 0 ;
return env -> eip + env -> segs [ R_CS ]. base ;
1884
1885
1886
}
# endif
1887
# if defined ( TARGET_PPC )
1888
static target_long monitor_get_ccr ( const struct MonitorDef * md , int val )
1889
{
1890
CPUState * env = mon_get_cpu ();
1891
1892
1893
unsigned int u ;
int i ;
1894
1895
1896
if ( ! env )
return 0 ;
1897
1898
u = 0 ;
for ( i = 0 ; i < 8 ; i ++ )
1899
u |= env -> crf [ i ] << ( 32 - ( 4 * i ));
1900
1901
1902
1903
return u ;
}
1904
static target_long monitor_get_msr ( const struct MonitorDef * md , int val )
1905
{
1906
1907
1908
CPUState * env = mon_get_cpu ();
if ( ! env )
return 0 ;
1909
return env -> msr ;
1910
1911
}
1912
static target_long monitor_get_xer ( const struct MonitorDef * md , int val )
1913
{
1914
1915
1916
CPUState * env = mon_get_cpu ();
if ( ! env )
return 0 ;
1917
return env -> xer ;
1918
}
1919
1920
static target_long monitor_get_decr ( const struct MonitorDef * md , int val )
1921
{
1922
1923
1924
1925
CPUState * env = mon_get_cpu ();
if ( ! env )
return 0 ;
return cpu_ppc_load_decr ( env );
1926
1927
}
1928
static target_long monitor_get_tbu ( const struct MonitorDef * md , int val )
1929
{
1930
1931
1932
1933
CPUState * env = mon_get_cpu ();
if ( ! env )
return 0 ;
return cpu_ppc_load_tbu ( env );
1934
1935
}
1936
static target_long monitor_get_tbl ( const struct MonitorDef * md , int val )
1937
{
1938
1939
1940
1941
CPUState * env = mon_get_cpu ();
if ( ! env )
return 0 ;
return cpu_ppc_load_tbl ( env );
1942
}
1943
1944
# endif
1945
# if defined ( TARGET_SPARC )
1946
# ifndef TARGET_SPARC64
1947
static target_long monitor_get_psr ( const struct MonitorDef * md , int val )
1948
{
1949
1950
1951
1952
CPUState * env = mon_get_cpu ();
if ( ! env )
return 0 ;
return GET_PSR ( env );
1953
}
1954
# endif
1955
1956
static target_long monitor_get_reg ( const struct MonitorDef * md , int val )
1957
{
1958
1959
1960
1961
CPUState * env = mon_get_cpu ();
if ( ! env )
return 0 ;
return env -> regwptr [ val ];
1962
1963
1964
}
# endif
1965
static const MonitorDef monitor_defs [] = {
1966
# ifdef TARGET_I386
1967
1968
# define SEG ( name , seg ) \
1969
{ name , offsetof ( CPUState , segs [ seg ]. selector ), NULL , MD_I32 }, \
1970
{ name ".base" , offsetof ( CPUState , segs [ seg ]. base ) }, \
1971
{ name ".limit" , offsetof ( CPUState , segs [ seg ]. limit ), NULL , MD_I32 },
1972
1973
1974
1975
1976
1977
1978
1979
{ "eax" , offsetof ( CPUState , regs [ 0 ]) },
{ "ecx" , offsetof ( CPUState , regs [ 1 ]) },
{ "edx" , offsetof ( CPUState , regs [ 2 ]) },
{ "ebx" , offsetof ( CPUState , regs [ 3 ]) },
{ "esp|sp" , offsetof ( CPUState , regs [ 4 ]) },
{ "ebp|fp" , offsetof ( CPUState , regs [ 5 ]) },
{ "esi" , offsetof ( CPUState , regs [ 6 ]) },
1980
{ "edi" , offsetof ( CPUState , regs [ 7 ]) },
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
# ifdef TARGET_X86_64
{ "r8" , offsetof ( CPUState , regs [ 8 ]) },
{ "r9" , offsetof ( CPUState , regs [ 9 ]) },
{ "r10" , offsetof ( CPUState , regs [ 10 ]) },
{ "r11" , offsetof ( CPUState , regs [ 11 ]) },
{ "r12" , offsetof ( CPUState , regs [ 12 ]) },
{ "r13" , offsetof ( CPUState , regs [ 13 ]) },
{ "r14" , offsetof ( CPUState , regs [ 14 ]) },
{ "r15" , offsetof ( CPUState , regs [ 15 ]) },
# endif
1991
{ "eflags" , offsetof ( CPUState , eflags ) },
1992
1993
1994
1995
{ "eip" , offsetof ( CPUState , eip ) },
SEG ( "cs" , R_CS )
SEG ( "ds" , R_DS )
SEG ( "es" , R_ES )
1996
SEG ( "ss" , R_SS )
1997
1998
1999
SEG ( "fs" , R_FS )
SEG ( "gs" , R_GS )
{ "pc" , 0 , monitor_get_pc , },
2000
# elif defined ( TARGET_PPC )
2001
/* General purpose registers */
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
{ "r0" , offsetof ( CPUState , gpr [ 0 ]) },
{ "r1" , offsetof ( CPUState , gpr [ 1 ]) },
{ "r2" , offsetof ( CPUState , gpr [ 2 ]) },
{ "r3" , offsetof ( CPUState , gpr [ 3 ]) },
{ "r4" , offsetof ( CPUState , gpr [ 4 ]) },
{ "r5" , offsetof ( CPUState , gpr [ 5 ]) },
{ "r6" , offsetof ( CPUState , gpr [ 6 ]) },
{ "r7" , offsetof ( CPUState , gpr [ 7 ]) },
{ "r8" , offsetof ( CPUState , gpr [ 8 ]) },
{ "r9" , offsetof ( CPUState , gpr [ 9 ]) },
{ "r10" , offsetof ( CPUState , gpr [ 10 ]) },
{ "r11" , offsetof ( CPUState , gpr [ 11 ]) },
{ "r12" , offsetof ( CPUState , gpr [ 12 ]) },
{ "r13" , offsetof ( CPUState , gpr [ 13 ]) },
{ "r14" , offsetof ( CPUState , gpr [ 14 ]) },
{ "r15" , offsetof ( CPUState , gpr [ 15 ]) },
{ "r16" , offsetof ( CPUState , gpr [ 16 ]) },
{ "r17" , offsetof ( CPUState , gpr [ 17 ]) },
{ "r18" , offsetof ( CPUState , gpr [ 18 ]) },
{ "r19" , offsetof ( CPUState , gpr [ 19 ]) },
{ "r20" , offsetof ( CPUState , gpr [ 20 ]) },
{ "r21" , offsetof ( CPUState , gpr [ 21 ]) },
{ "r22" , offsetof ( CPUState , gpr [ 22 ]) },
{ "r23" , offsetof ( CPUState , gpr [ 23 ]) },
{ "r24" , offsetof ( CPUState , gpr [ 24 ]) },
{ "r25" , offsetof ( CPUState , gpr [ 25 ]) },
{ "r26" , offsetof ( CPUState , gpr [ 26 ]) },
{ "r27" , offsetof ( CPUState , gpr [ 27 ]) },
{ "r28" , offsetof ( CPUState , gpr [ 28 ]) },
{ "r29" , offsetof ( CPUState , gpr [ 29 ]) },
{ "r30" , offsetof ( CPUState , gpr [ 30 ]) },
{ "r31" , offsetof ( CPUState , gpr [ 31 ]) },
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
/* Floating point registers */
{ "f0" , offsetof ( CPUState , fpr [ 0 ]) },
{ "f1" , offsetof ( CPUState , fpr [ 1 ]) },
{ "f2" , offsetof ( CPUState , fpr [ 2 ]) },
{ "f3" , offsetof ( CPUState , fpr [ 3 ]) },
{ "f4" , offsetof ( CPUState , fpr [ 4 ]) },
{ "f5" , offsetof ( CPUState , fpr [ 5 ]) },
{ "f6" , offsetof ( CPUState , fpr [ 6 ]) },
{ "f7" , offsetof ( CPUState , fpr [ 7 ]) },
{ "f8" , offsetof ( CPUState , fpr [ 8 ]) },
{ "f9" , offsetof ( CPUState , fpr [ 9 ]) },
{ "f10" , offsetof ( CPUState , fpr [ 10 ]) },
{ "f11" , offsetof ( CPUState , fpr [ 11 ]) },
{ "f12" , offsetof ( CPUState , fpr [ 12 ]) },
{ "f13" , offsetof ( CPUState , fpr [ 13 ]) },
{ "f14" , offsetof ( CPUState , fpr [ 14 ]) },
{ "f15" , offsetof ( CPUState , fpr [ 15 ]) },
{ "f16" , offsetof ( CPUState , fpr [ 16 ]) },
{ "f17" , offsetof ( CPUState , fpr [ 17 ]) },
{ "f18" , offsetof ( CPUState , fpr [ 18 ]) },
{ "f19" , offsetof ( CPUState , fpr [ 19 ]) },
{ "f20" , offsetof ( CPUState , fpr [ 20 ]) },
{ "f21" , offsetof ( CPUState , fpr [ 21 ]) },
{ "f22" , offsetof ( CPUState , fpr [ 22 ]) },
{ "f23" , offsetof ( CPUState , fpr [ 23 ]) },
{ "f24" , offsetof ( CPUState , fpr [ 24 ]) },
{ "f25" , offsetof ( CPUState , fpr [ 25 ]) },
{ "f26" , offsetof ( CPUState , fpr [ 26 ]) },
{ "f27" , offsetof ( CPUState , fpr [ 27 ]) },
{ "f28" , offsetof ( CPUState , fpr [ 28 ]) },
{ "f29" , offsetof ( CPUState , fpr [ 29 ]) },
{ "f30" , offsetof ( CPUState , fpr [ 30 ]) },
{ "f31" , offsetof ( CPUState , fpr [ 31 ]) },
{ "fpscr" , offsetof ( CPUState , fpscr ) },
/* Next instruction pointer */
2069
{ "nip|pc" , offsetof ( CPUState , nip ) },
2070
2071
{ "lr" , offsetof ( CPUState , lr ) },
{ "ctr" , offsetof ( CPUState , ctr ) },
2072
{ "decr" , 0 , & monitor_get_decr , },
2073
{ "ccr" , 0 , & monitor_get_ccr , },
2074
/* Machine state register */
2075
2076
{ "msr" , 0 , & monitor_get_msr , },
{ "xer" , 0 , & monitor_get_xer , },
2077
2078
{ "tbu" , 0 , & monitor_get_tbu , },
{ "tbl" , 0 , & monitor_get_tbl , },
2079
2080
2081
2082
2083
# if defined ( TARGET_PPC64 )
/* Address space register */
{ "asr" , offsetof ( CPUState , asr ) },
# endif
/* Segment registers */
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
{ "sdr1" , offsetof ( CPUState , sdr1 ) },
{ "sr0" , offsetof ( CPUState , sr [ 0 ]) },
{ "sr1" , offsetof ( CPUState , sr [ 1 ]) },
{ "sr2" , offsetof ( CPUState , sr [ 2 ]) },
{ "sr3" , offsetof ( CPUState , sr [ 3 ]) },
{ "sr4" , offsetof ( CPUState , sr [ 4 ]) },
{ "sr5" , offsetof ( CPUState , sr [ 5 ]) },
{ "sr6" , offsetof ( CPUState , sr [ 6 ]) },
{ "sr7" , offsetof ( CPUState , sr [ 7 ]) },
{ "sr8" , offsetof ( CPUState , sr [ 8 ]) },
{ "sr9" , offsetof ( CPUState , sr [ 9 ]) },
{ "sr10" , offsetof ( CPUState , sr [ 10 ]) },
{ "sr11" , offsetof ( CPUState , sr [ 11 ]) },
{ "sr12" , offsetof ( CPUState , sr [ 12 ]) },
{ "sr13" , offsetof ( CPUState , sr [ 13 ]) },
{ "sr14" , offsetof ( CPUState , sr [ 14 ]) },
{ "sr15" , offsetof ( CPUState , sr [ 15 ]) },
/* Too lazy to put BATs and SPRs ... */
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
# elif defined ( TARGET_SPARC )
{ "g0" , offsetof ( CPUState , gregs [ 0 ]) },
{ "g1" , offsetof ( CPUState , gregs [ 1 ]) },
{ "g2" , offsetof ( CPUState , gregs [ 2 ]) },
{ "g3" , offsetof ( CPUState , gregs [ 3 ]) },
{ "g4" , offsetof ( CPUState , gregs [ 4 ]) },
{ "g5" , offsetof ( CPUState , gregs [ 5 ]) },
{ "g6" , offsetof ( CPUState , gregs [ 6 ]) },
{ "g7" , offsetof ( CPUState , gregs [ 7 ]) },
{ "o0" , 0 , monitor_get_reg },
{ "o1" , 1 , monitor_get_reg },
{ "o2" , 2 , monitor_get_reg },
{ "o3" , 3 , monitor_get_reg },
{ "o4" , 4 , monitor_get_reg },
{ "o5" , 5 , monitor_get_reg },
{ "o6" , 6 , monitor_get_reg },
{ "o7" , 7 , monitor_get_reg },
{ "l0" , 8 , monitor_get_reg },
{ "l1" , 9 , monitor_get_reg },
{ "l2" , 10 , monitor_get_reg },
{ "l3" , 11 , monitor_get_reg },
{ "l4" , 12 , monitor_get_reg },
{ "l5" , 13 , monitor_get_reg },
{ "l6" , 14 , monitor_get_reg },
{ "l7" , 15 , monitor_get_reg },
{ "i0" , 16 , monitor_get_reg },
{ "i1" , 17 , monitor_get_reg },
{ "i2" , 18 , monitor_get_reg },
{ "i3" , 19 , monitor_get_reg },
{ "i4" , 20 , monitor_get_reg },
{ "i5" , 21 , monitor_get_reg },
{ "i6" , 22 , monitor_get_reg },
{ "i7" , 23 , monitor_get_reg },
{ "pc" , offsetof ( CPUState , pc ) },
{ "npc" , offsetof ( CPUState , npc ) },
{ "y" , offsetof ( CPUState , y ) },
2138
# ifndef TARGET_SPARC64
2139
2140
{ "psr" , 0 , & monitor_get_psr , },
{ "wim" , offsetof ( CPUState , wim ) },
2141
# endif
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
{ "tbr" , offsetof ( CPUState , tbr ) },
{ "fsr" , offsetof ( CPUState , fsr ) },
{ "f0" , offsetof ( CPUState , fpr [ 0 ]) },
{ "f1" , offsetof ( CPUState , fpr [ 1 ]) },
{ "f2" , offsetof ( CPUState , fpr [ 2 ]) },
{ "f3" , offsetof ( CPUState , fpr [ 3 ]) },
{ "f4" , offsetof ( CPUState , fpr [ 4 ]) },
{ "f5" , offsetof ( CPUState , fpr [ 5 ]) },
{ "f6" , offsetof ( CPUState , fpr [ 6 ]) },
{ "f7" , offsetof ( CPUState , fpr [ 7 ]) },
{ "f8" , offsetof ( CPUState , fpr [ 8 ]) },
{ "f9" , offsetof ( CPUState , fpr [ 9 ]) },
{ "f10" , offsetof ( CPUState , fpr [ 10 ]) },
{ "f11" , offsetof ( CPUState , fpr [ 11 ]) },
{ "f12" , offsetof ( CPUState , fpr [ 12 ]) },
{ "f13" , offsetof ( CPUState , fpr [ 13 ]) },
{ "f14" , offsetof ( CPUState , fpr [ 14 ]) },
{ "f15" , offsetof ( CPUState , fpr [ 15 ]) },
{ "f16" , offsetof ( CPUState , fpr [ 16 ]) },
{ "f17" , offsetof ( CPUState , fpr [ 17 ]) },
{ "f18" , offsetof ( CPUState , fpr [ 18 ]) },
{ "f19" , offsetof ( CPUState , fpr [ 19 ]) },
{ "f20" , offsetof ( CPUState , fpr [ 20 ]) },
{ "f21" , offsetof ( CPUState , fpr [ 21 ]) },
{ "f22" , offsetof ( CPUState , fpr [ 22 ]) },
{ "f23" , offsetof ( CPUState , fpr [ 23 ]) },
{ "f24" , offsetof ( CPUState , fpr [ 24 ]) },
{ "f25" , offsetof ( CPUState , fpr [ 25 ]) },
{ "f26" , offsetof ( CPUState , fpr [ 26 ]) },
{ "f27" , offsetof ( CPUState , fpr [ 27 ]) },
{ "f28" , offsetof ( CPUState , fpr [ 28 ]) },
{ "f29" , offsetof ( CPUState , fpr [ 29 ]) },
{ "f30" , offsetof ( CPUState , fpr [ 30 ]) },
{ "f31" , offsetof ( CPUState , fpr [ 31 ]) },
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
# ifdef TARGET_SPARC64
{ "f32" , offsetof ( CPUState , fpr [ 32 ]) },
{ "f34" , offsetof ( CPUState , fpr [ 34 ]) },
{ "f36" , offsetof ( CPUState , fpr [ 36 ]) },
{ "f38" , offsetof ( CPUState , fpr [ 38 ]) },
{ "f40" , offsetof ( CPUState , fpr [ 40 ]) },
{ "f42" , offsetof ( CPUState , fpr [ 42 ]) },
{ "f44" , offsetof ( CPUState , fpr [ 44 ]) },
{ "f46" , offsetof ( CPUState , fpr [ 46 ]) },
{ "f48" , offsetof ( CPUState , fpr [ 48 ]) },
{ "f50" , offsetof ( CPUState , fpr [ 50 ]) },
{ "f52" , offsetof ( CPUState , fpr [ 52 ]) },
{ "f54" , offsetof ( CPUState , fpr [ 54 ]) },
{ "f56" , offsetof ( CPUState , fpr [ 56 ]) },
{ "f58" , offsetof ( CPUState , fpr [ 58 ]) },
{ "f60" , offsetof ( CPUState , fpr [ 60 ]) },
{ "f62" , offsetof ( CPUState , fpr [ 62 ]) },
{ "asi" , offsetof ( CPUState , asi ) },
{ "pstate" , offsetof ( CPUState , pstate ) },
{ "cansave" , offsetof ( CPUState , cansave ) },
{ "canrestore" , offsetof ( CPUState , canrestore ) },
{ "otherwin" , offsetof ( CPUState , otherwin ) },
{ "wstate" , offsetof ( CPUState , wstate ) },
{ "cleanwin" , offsetof ( CPUState , cleanwin ) },
{ "fprs" , offsetof ( CPUState , fprs ) },
# endif
2202
2203
2204
2205
# endif
{ NULL },
};
2206
static void expr_error ( Monitor * mon , const char * msg )
2207
{
2208
monitor_printf ( mon , "%s \n " , msg );
2209
2210
2211
longjmp ( expr_env , 1 );
}
2212
/* return 0 if OK, -1 if not found, -2 if no CPU defined */
2213
static int get_monitor_def ( target_long * pval , const char * name )
2214
{
2215
const MonitorDef * md ;
2216
2217
void * ptr ;
2218
2219
2220
for ( md = monitor_defs ; md -> name != NULL ; md ++ ) {
if ( compare_cmd ( name , md -> name )) {
if ( md -> get_value ) {
2221
* pval = md -> get_value ( md , md -> offset );
2222
} else {
2223
2224
2225
2226
CPUState * env = mon_get_cpu ();
if ( ! env )
return - 2 ;
ptr = ( uint8_t * ) env + md -> offset ;
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
switch ( md -> type ) {
case MD_I32 :
* pval = * ( int32_t * ) ptr ;
break ;
case MD_TLONG :
* pval = * ( target_long * ) ptr ;
break ;
default :
* pval = 0 ;
break ;
}
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
}
return 0 ;
}
}
return - 1 ;
}
static void next ( void )
{
if ( pch != '\0' ) {
pch ++ ;
2249
while ( qemu_isspace ( * pch ))
2250
2251
2252
2253
pch ++ ;
}
}
2254
static int64_t expr_sum ( Monitor * mon );
2255
2256
static int64_t expr_unary ( Monitor * mon )
2257
{
2258
int64_t n ;
2259
char * p ;
2260
int ret ;
2261
2262
2263
2264
switch ( * pch ) {
case '+' :
next ();
2265
n = expr_unary ( mon );
2266
2267
2268
break ;
case '-' :
next ();
2269
n = - expr_unary ( mon );
2270
2271
2272
break ;
case '~' :
next ();
2273
n = ~ expr_unary ( mon );
2274
2275
2276
break ;
case '(' :
next ();
2277
n = expr_sum ( mon );
2278
if ( * pch != ')' ) {
2279
expr_error ( mon , "')' expected" );
2280
2281
2282
}
next ();
break ;
2283
2284
2285
case '\'' :
pch ++ ;
if ( * pch == '\0' )
2286
expr_error ( mon , "character constant expected" );
2287
2288
2289
n = * pch ;
pch ++ ;
if ( * pch != '\'' )
2290
expr_error ( mon , "missing terminating \' character" );
2291
2292
next ();
break ;
2293
2294
2295
case '$' :
{
char buf [ 128 ], * q ;
ths
authored
17 years ago
2296
target_long reg = 0 ;
ths
authored
18 years ago
2297
2298
2299
2300
2301
2302
pch ++ ;
q = buf ;
while (( * pch >= 'a' && * pch <= 'z' ) ||
( * pch >= 'A' && * pch <= 'Z' ) ||
( * pch >= '0' && * pch <= '9' ) ||
2303
* pch == '_' || * pch == '.' ) {
2304
2305
2306
2307
if (( q - buf ) < sizeof ( buf ) - 1 )
* q ++ = * pch ;
pch ++ ;
}
2308
while ( qemu_isspace ( * pch ))
2309
2310
pch ++ ;
* q = 0 ;
2311
ret = get_monitor_def ( & reg , buf );
2312
if ( ret == - 1 )
2313
expr_error ( mon , "unknown register" );
ths
authored
18 years ago
2314
else if ( ret == - 2 )
2315
expr_error ( mon , "no cpu defined" );
2316
n = reg ;
2317
2318
2319
}
break ;
case '\0' :
2320
expr_error ( mon , "unexpected end of expression" );
2321
2322
2323
n = 0 ;
break ;
default :
2324
# if TARGET_PHYS_ADDR_BITS > 32
2325
2326
n = strtoull ( pch , & p , 0 );
# else
2327
n = strtoul ( pch , & p , 0 );
2328
# endif
2329
if ( pch == p ) {
2330
expr_error ( mon , "invalid char in expression" );
2331
2332
}
pch = p ;
2333
while ( qemu_isspace ( * pch ))
2334
2335
2336
2337
2338
2339
2340
pch ++ ;
break ;
}
return n ;
}
2341
static int64_t expr_prod ( Monitor * mon )
2342
{
2343
int64_t val , val2 ;
2344
int op ;
ths
authored
18 years ago
2345
2346
val = expr_unary ( mon );
2347
2348
2349
2350
2351
for (;;) {
op = * pch ;
if ( op != '*' && op != '/' && op != '%' )
break ;
next ();
2352
val2 = expr_unary ( mon );
2353
2354
2355
2356
2357
2358
2359
switch ( op ) {
default :
case '*' :
val *= val2 ;
break ;
case '/' :
case '%' :
ths
authored
18 years ago
2360
if ( val2 == 0 )
2361
expr_error ( mon , "division by zero" );
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
if ( op == '/' )
val /= val2 ;
else
val %= val2 ;
break ;
}
}
return val ;
}
2372
static int64_t expr_logic ( Monitor * mon )
2373
{
2374
int64_t val , val2 ;
2375
int op ;
2376
2377
val = expr_prod ( mon );
2378
2379
2380
2381
2382
for (;;) {
op = * pch ;
if ( op != '&' && op != '|' && op != '^' )
break ;
next ();
2383
val2 = expr_prod ( mon );
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
switch ( op ) {
default :
case '&' :
val &= val2 ;
break ;
case '|' :
val |= val2 ;
break ;
case '^' :
val ^= val2 ;
break ;
}
}
return val ;
}
2400
static int64_t expr_sum ( Monitor * mon )
2401
{
2402
int64_t val , val2 ;
2403
int op ;
2404
2405
val = expr_logic ( mon );
2406
2407
2408
2409
2410
for (;;) {
op = * pch ;
if ( op != '+' && op != '-' )
break ;
next ();
2411
val2 = expr_logic ( mon );
2412
2413
2414
2415
2416
2417
2418
2419
if ( op == '+' )
val += val2 ;
else
val -= val2 ;
}
return val ;
}
2420
static int get_expr ( Monitor * mon , int64_t * pval , const char ** pp )
2421
2422
2423
2424
2425
2426
{
pch = * pp ;
if ( setjmp ( expr_env )) {
* pp = pch ;
return - 1 ;
}
2427
while ( qemu_isspace ( * pch ))
2428
pch ++ ;
2429
* pval = expr_sum ( mon );
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
* pp = pch ;
return 0 ;
}
static int get_str ( char * buf , int buf_size , const char ** pp )
{
const char * p ;
char * q ;
int c ;
2440
q = buf ;
2441
p = * pp ;
2442
while ( qemu_isspace ( * p ))
2443
2444
2445
p ++ ;
if ( * p == '\0' ) {
fail :
2446
* q = '\0' ;
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
* pp = p ;
return - 1 ;
}
if ( * p == '\"' ) {
p ++ ;
while ( * p != '\0' && * p != '\"' ) {
if ( * p == '\\' ) {
p ++ ;
c = * p ++ ;
switch ( c ) {
case 'n' :
c = '\n' ;
break ;
case 'r' :
c = '\r' ;
break ;
case '\\' :
case '\'' :
case '\"' :
break ;
default :
qemu_printf ( "unsupported escape code: ' \\ %c' \n " , c );
goto fail ;
}
if (( q - buf ) < buf_size - 1 ) {
* q ++ = c ;
}
} else {
if (( q - buf ) < buf_size - 1 ) {
* q ++ = * p ;
}
p ++ ;
}
}
if ( * p != '\"' ) {
2482
qemu_printf ( "unterminated string \n " );
2483
2484
2485
2486
goto fail ;
}
p ++ ;
} else {
2487
while ( * p != '\0' && ! qemu_isspace ( * p )) {
2488
2489
2490
2491
2492
2493
if (( q - buf ) < buf_size - 1 ) {
* q ++ = * p ;
}
p ++ ;
}
}
2494
* q = '\0' ;
2495
2496
2497
2498
2499
2500
2501
2502
2503
* pp = p ;
return 0 ;
}
static int default_fmt_format = 'x' ;
static int default_fmt_size = 4 ;
# define MAX_ARGS 16
2504
static void monitor_handle_command ( Monitor * mon , const char * cmdline )
2505
2506
2507
2508
{
const char * p , * pstart , * typestr ;
char * q ;
int c , nb_args , len , i , has_arg ;
2509
const mon_cmd_t * cmd ;
2510
2511
2512
2513
char cmdname [ 256 ];
char buf [ 1024 ];
void * str_allocated [ MAX_ARGS ];
void * args [ MAX_ARGS ];
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
void ( * handler_0 )( Monitor * mon );
void ( * handler_1 )( Monitor * mon , void * arg0 );
void ( * handler_2 )( Monitor * mon , void * arg0 , void * arg1 );
void ( * handler_3 )( Monitor * mon , void * arg0 , void * arg1 , void * arg2 );
void ( * handler_4 )( Monitor * mon , void * arg0 , void * arg1 , void * arg2 ,
void * arg3 );
void ( * handler_5 )( Monitor * mon , void * arg0 , void * arg1 , void * arg2 ,
void * arg3 , void * arg4 );
void ( * handler_6 )( Monitor * mon , void * arg0 , void * arg1 , void * arg2 ,
void * arg3 , void * arg4 , void * arg5 );
void ( * handler_7 )( Monitor * mon , void * arg0 , void * arg1 , void * arg2 ,
void * arg3 , void * arg4 , void * arg5 , void * arg6 );
2526
2527
# ifdef DEBUG
2528
monitor_printf ( mon , "command='%s' \n " , cmdline );
2529
# endif
ths
authored
18 years ago
2530
2531
/* extract the command name */
2532
p = cmdline ;
2533
q = cmdname ;
2534
while ( qemu_isspace ( * p ))
2535
2536
2537
2538
p ++ ;
if ( * p == '\0' )
return ;
pstart = p ;
2539
while ( * p != '\0' && * p != '/' && ! qemu_isspace ( * p ))
2540
2541
2542
2543
2544
2545
p ++ ;
len = p - pstart ;
if ( len > sizeof ( cmdname ) - 1 )
len = sizeof ( cmdname ) - 1 ;
memcpy ( cmdname , pstart , len );
cmdname [ len ] = '\0' ;
ths
authored
18 years ago
2546
2547
/* find the command */
2548
for ( cmd = mon_cmds ; cmd -> name != NULL ; cmd ++ ) {
ths
authored
18 years ago
2549
if ( compare_cmd ( cmdname , cmd -> name ))
2550
2551
goto found ;
}
2552
monitor_printf ( mon , "unknown command: '%s' \n " , cmdname );
2553
2554
2555
2556
2557
return ;
found :
for ( i = 0 ; i < MAX_ARGS ; i ++ )
str_allocated [ i ] = NULL ;
ths
authored
18 years ago
2558
2559
2560
2561
/* parse the parameters */
typestr = cmd -> args_type ;
nb_args = 0 ;
2562
for (;;) {
2563
2564
c = * typestr ;
if ( c == '\0' )
2565
break ;
2566
2567
2568
typestr ++ ;
switch ( c ) {
case 'F' :
2569
case 'B' :
2570
2571
2572
2573
case 's' :
{
int ret ;
char * str ;
ths
authored
18 years ago
2574
2575
while ( qemu_isspace ( * p ))
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
p ++ ;
if ( * typestr == '?' ) {
typestr ++ ;
if ( * p == '\0' ) {
/* no optional string: NULL argument */
str = NULL ;
goto add_str ;
}
}
ret = get_str ( buf , sizeof ( buf ), & p );
if ( ret < 0 ) {
2587
2588
switch ( c ) {
case 'F' :
2589
2590
monitor_printf ( mon , "%s: filename expected \n " ,
cmdname );
2591
2592
break ;
case 'B' :
2593
2594
monitor_printf ( mon , "%s: block device name expected \n " ,
cmdname );
2595
2596
break ;
default :
2597
monitor_printf ( mon , "%s: string expected \n " , cmdname );
2598
2599
break ;
}
2600
2601
2602
goto fail ;
}
str = qemu_malloc ( strlen ( buf ) + 1 );
2603
pstrcpy ( str , sizeof ( buf ), buf );
2604
2605
2606
2607
str_allocated [ nb_args ] = str ;
add_str :
if ( nb_args >= MAX_ARGS ) {
error_args :
2608
monitor_printf ( mon , "%s: too many arguments \n " , cmdname );
2609
2610
2611
2612
goto fail ;
}
args [ nb_args ++ ] = str ;
}
2613
break ;
2614
2615
2616
case '/' :
{
int count , format , size ;
ths
authored
18 years ago
2617
2618
while ( qemu_isspace ( * p ))
2619
2620
2621
2622
2623
p ++ ;
if ( * p == '/' ) {
/* format found */
p ++ ;
count = 1 ;
2624
if ( qemu_isdigit ( * p )) {
2625
count = 0 ;
2626
while ( qemu_isdigit ( * p )) {
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
count = count * 10 + ( * p - '0' );
p ++ ;
}
}
size = - 1 ;
format = - 1 ;
for (;;) {
switch ( * p ) {
case 'o' :
case 'd' :
case 'u' :
case 'x' :
case 'i' :
case 'c' :
format = * p ++ ;
break ;
case 'b' :
size = 1 ;
p ++ ;
break ;
case 'h' :
size = 2 ;
p ++ ;
break ;
case 'w' :
size = 4 ;
p ++ ;
break ;
case 'g' :
case 'L' :
size = 8 ;
p ++ ;
break ;
default :
goto next ;
}
}
next :
2665
if ( * p != '\0' && ! qemu_isspace ( * p )) {
2666
2667
monitor_printf ( mon , "invalid char in format: '%c' \n " ,
* p );
2668
2669
2670
2671
goto fail ;
}
if ( format < 0 )
format = default_fmt_format ;
2672
2673
2674
2675
if ( format != 'i' ) {
/* for 'i', not specifying a size gives -1 as size */
if ( size < 0 )
size = default_fmt_size ;
2676
default_fmt_size = size ;
2677
}
2678
2679
2680
2681
default_fmt_format = format ;
} else {
count = 1 ;
format = default_fmt_format ;
2682
2683
2684
2685
2686
if ( format != 'i' ) {
size = default_fmt_size ;
} else {
size = - 1 ;
}
2687
2688
2689
}
if ( nb_args + 3 > MAX_ARGS )
goto error_args ;
2690
2691
2692
args [ nb_args ++ ] = ( void * )( long ) count ;
args [ nb_args ++ ] = ( void * )( long ) format ;
args [ nb_args ++ ] = ( void * )( long ) size ;
2693
}
2694
break ;
2695
case 'i' :
2696
case 'l' :
2697
{
2698
int64_t val ;
2699
2700
while ( qemu_isspace ( * p ))
2701
p ++ ;
2702
2703
2704
2705
2706
2707
2708
2709
2710
if ( * typestr == '?' || * typestr == '.' ) {
if ( * typestr == '?' ) {
if ( * p == '\0' )
has_arg = 0 ;
else
has_arg = 1 ;
} else {
if ( * p == '.' ) {
p ++ ;
2711
while ( qemu_isspace ( * p ))
2712
2713
2714
2715
2716
2717
p ++ ;
has_arg = 1 ;
} else {
has_arg = 0 ;
}
}
2718
typestr ++ ;
2719
2720
if ( nb_args >= MAX_ARGS )
goto error_args ;
2721
args [ nb_args ++ ] = ( void * )( long ) has_arg ;
2722
2723
2724
2725
2726
2727
2728
if ( ! has_arg ) {
if ( nb_args >= MAX_ARGS )
goto error_args ;
val = - 1 ;
goto add_num ;
}
}
2729
if ( get_expr ( mon , & val , & p ))
2730
2731
goto fail ;
add_num :
2732
2733
2734
if ( c == 'i' ) {
if ( nb_args >= MAX_ARGS )
goto error_args ;
2735
args [ nb_args ++ ] = ( void * )( long ) val ;
2736
2737
2738
} else {
if (( nb_args + 1 ) >= MAX_ARGS )
goto error_args ;
2739
# if TARGET_PHYS_ADDR_BITS > 32
2740
args [ nb_args ++ ] = ( void * )( long )(( val >> 32 ) & 0xffffffff );
2741
2742
2743
# else
args [ nb_args ++ ] = ( void * ) 0 ;
# endif
2744
args [ nb_args ++ ] = ( void * )( long )( val & 0xffffffff );
2745
}
2746
2747
2748
2749
2750
2751
}
break ;
case '-' :
{
int has_option ;
/* option */
ths
authored
18 years ago
2752
2753
2754
2755
c = * typestr ++ ;
if ( c == '\0' )
goto bad_type ;
2756
while ( qemu_isspace ( * p ))
2757
2758
2759
2760
2761
p ++ ;
has_option = 0 ;
if ( * p == '-' ) {
p ++ ;
if ( * p != c ) {
2762
2763
monitor_printf ( mon , "%s: unsupported option -%c \n " ,
cmdname , * p );
2764
2765
2766
2767
2768
2769
2770
goto fail ;
}
p ++ ;
has_option = 1 ;
}
if ( nb_args >= MAX_ARGS )
goto error_args ;
2771
args [ nb_args ++ ] = ( void * )( long ) has_option ;
2772
2773
2774
2775
}
break ;
default :
bad_type :
2776
monitor_printf ( mon , "%s: unknown type '%c' \n " , cmdname , c );
2777
2778
goto fail ;
}
2779
}
2780
/* check that all arguments were parsed */
2781
while ( qemu_isspace ( * p ))
2782
2783
p ++ ;
if ( * p != '\0' ) {
2784
2785
monitor_printf ( mon , "%s: extraneous characters at the end of line \n " ,
cmdname );
2786
goto fail ;
2787
}
2788
2789
2790
switch ( nb_args ) {
case 0 :
2791
handler_0 = cmd -> handler ;
2792
handler_0 ( mon );
2793
2794
break ;
case 1 :
2795
handler_1 = cmd -> handler ;
2796
handler_1 ( mon , args [ 0 ]);
2797
2798
break ;
case 2 :
2799
handler_2 = cmd -> handler ;
2800
handler_2 ( mon , args [ 0 ], args [ 1 ]);
2801
2802
break ;
case 3 :
2803
handler_3 = cmd -> handler ;
2804
handler_3 ( mon , args [ 0 ], args [ 1 ], args [ 2 ]);
2805
2806
break ;
case 4 :
2807
handler_4 = cmd -> handler ;
2808
handler_4 ( mon , args [ 0 ], args [ 1 ], args [ 2 ], args [ 3 ]);
2809
2810
break ;
case 5 :
2811
handler_5 = cmd -> handler ;
2812
handler_5 ( mon , args [ 0 ], args [ 1 ], args [ 2 ], args [ 3 ], args [ 4 ]);
2813
break ;
2814
case 6 :
2815
handler_6 = cmd -> handler ;
2816
handler_6 ( mon , args [ 0 ], args [ 1 ], args [ 2 ], args [ 3 ], args [ 4 ], args [ 5 ]);
2817
break ;
2818
case 7 :
2819
handler_7 = cmd -> handler ;
2820
2821
handler_7 ( mon , args [ 0 ], args [ 1 ], args [ 2 ], args [ 3 ], args [ 4 ], args [ 5 ],
args [ 6 ]);
2822
break ;
2823
default :
2824
monitor_printf ( mon , "unsupported number of arguments: %d \n " , nb_args );
2825
goto fail ;
2826
}
2827
2828
2829
fail :
for ( i = 0 ; i < MAX_ARGS ; i ++ )
qemu_free ( str_allocated [ i ]);
2830
2831
2832
return ;
}
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
static void cmd_completion ( const char * name , const char * list )
{
const char * p , * pstart ;
char cmd [ 128 ];
int len ;
p = list ;
for (;;) {
pstart = p ;
p = strchr ( p , '|' );
if ( ! p )
p = pstart + strlen ( pstart );
len = p - pstart ;
if ( len > sizeof ( cmd ) - 2 )
len = sizeof ( cmd ) - 2 ;
memcpy ( cmd , pstart , len );
cmd [ len ] = '\0' ;
if ( name [ 0 ] == '\0' || ! strncmp ( name , cmd , strlen ( name ))) {
2851
readline_add_completion ( cur_mon -> rs , cmd );
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
}
if ( * p == '\0' )
break ;
p ++ ;
}
}
static void file_completion ( const char * input )
{
DIR * ffs ;
struct dirent * d ;
char path [ 1024 ];
char file [ 1024 ], file_prefix [ 1024 ];
int input_path_len ;
const char * p ;
ths
authored
18 years ago
2868
p = strrchr ( input , '/' );
2869
2870
2871
if ( ! p ) {
input_path_len = 0 ;
pstrcpy ( file_prefix , sizeof ( file_prefix ), input );
2872
pstrcpy ( path , sizeof ( path ), "." );
2873
2874
2875
2876
2877
2878
2879
2880
2881
} else {
input_path_len = p - input + 1 ;
memcpy ( path , input , input_path_len );
if ( input_path_len > sizeof ( path ) - 1 )
input_path_len = sizeof ( path ) - 1 ;
path [ input_path_len ] = '\0' ;
pstrcpy ( file_prefix , sizeof ( file_prefix ), p + 1 );
}
# ifdef DEBUG_COMPLETION
2882
2883
monitor_printf ( cur_mon , "input='%s' path='%s' prefix='%s' \n " ,
input , path , file_prefix );
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
# endif
ffs = opendir ( path );
if ( ! ffs )
return ;
for (;;) {
struct stat sb ;
d = readdir ( ffs );
if ( ! d )
break ;
if ( strstart ( d -> d_name , file_prefix , NULL )) {
memcpy ( file , input , input_path_len );
2895
2896
2897
if ( input_path_len < sizeof ( file ))
pstrcpy ( file + input_path_len , sizeof ( file ) - input_path_len ,
d -> d_name );
2898
2899
2900
2901
2902
/* stat the file to find out if it ' s a directory .
* In that case add a slash to speed up typing long paths
*/
stat ( file , & sb ) ;
if ( S_ISDIR ( sb . st_mode ))
2903
pstrcat ( file , sizeof ( file ), "/" ) ;
2904
readline_add_completion ( cur_mon -> rs , file ) ;
2905
2906
2907
2908
2909
}
}
closedir ( ffs ) ;
}
2910
static void block_completion_it ( void * opaque , BlockDriverState * bs )
2911
{
2912
const char * name = bdrv_get_device_name ( bs ) ;
2913
2914
2915
2916
const char * input = opaque ;
if ( input [ 0 ] == '\0' ||
! strncmp ( name , ( char * ) input , strlen ( input ))) {
2917
readline_add_completion ( cur_mon -> rs , name ) ;
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
}
}
/* NOTE: this parser is an approximate form of the real command parser */
static void parse_cmdline ( const char * cmdline ,
int * pnb_args , char ** args )
{
const char * p ;
int nb_args , ret ;
char buf [ 1024 ] ;
p = cmdline ;
nb_args = 0 ;
for ( ;; ) {
2932
while ( qemu_isspace ( * p ))
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
p ++ ;
if ( * p == '\0' )
break ;
if ( nb_args >= MAX_ARGS )
break ;
ret = get_str ( buf , sizeof ( buf ), & p ) ;
args [ nb_args ] = qemu_strdup ( buf ) ;
nb_args ++ ;
if ( ret < 0 )
break ;
}
* pnb_args = nb_args ;
}
2947
static void monitor_find_completion ( const char * cmdline )
2948
2949
2950
2951
2952
{
const char * cmdname ;
char * args [ MAX_ARGS ] ;
int nb_args , i , len ;
const char * ptype , * str ;
2953
const mon_cmd_t * cmd ;
2954
const KeyDef * key ;
2955
2956
2957
2958
parse_cmdline ( cmdline , & nb_args , args ) ;
# ifdef DEBUG_COMPLETION
for ( i = 0 ; i < nb_args ; i ++ ) {
2959
monitor_printf ( cur_mon , "arg%d = '%s' \n " , i , ( char * ) args [ i ]) ;
2960
2961
2962
2963
2964
2965
}
# endif
/* if the line ends with a space , it means we want to complete the
next arg */
len = strlen ( cmdline ) ;
2966
if ( len > 0 && qemu_isspace ( cmdline [ len - 1 ])) {
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
if ( nb_args >= MAX_ARGS )
return ;
args [ nb_args ++ ] = qemu_strdup ( "" ) ;
}
if ( nb_args <= 1 ) {
/* command completion */
if ( nb_args == 0 )
cmdname = "" ;
else
cmdname = args [ 0 ] ;
2977
readline_set_completion_index ( cur_mon -> rs , strlen ( cmdname )) ;
2978
for ( cmd = mon_cmds ; cmd -> name != NULL ; cmd ++ ) {
2979
2980
2981
2982
cmd_completion ( cmdname , cmd -> name ) ;
}
} else {
/* find the command */
2983
for ( cmd = mon_cmds ; cmd -> name != NULL ; cmd ++ ) {
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
if ( compare_cmd ( args [ 0 ], cmd -> name ))
goto found ;
}
return ;
found :
ptype = cmd -> args_type ;
for ( i = 0 ; i < nb_args - 2 ; i ++ ) {
if ( * ptype != '\0' ) {
ptype ++ ;
while ( * ptype == '?' )
ptype ++ ;
}
}
str = args [ nb_args - 1 ];
switch ( * ptype ) {
case 'F' :
/* file completion */
3001
readline_set_completion_index ( cur_mon -> rs , strlen ( str ));
3002
3003
3004
3005
file_completion ( str );
break ;
case 'B' :
/* block device name completion */
3006
readline_set_completion_index ( cur_mon -> rs , strlen ( str ));
3007
3008
bdrv_iterate ( block_completion_it , ( void * ) str );
break ;
3009
3010
3011
case 's' :
/* XXX: more generic ? */
if ( ! strcmp ( cmd -> name , "info" )) {
3012
readline_set_completion_index ( cur_mon -> rs , strlen ( str ));
3013
3014
3015
for ( cmd = info_cmds ; cmd -> name != NULL ; cmd ++ ) {
cmd_completion ( str , cmd -> name );
}
3016
} else if ( ! strcmp ( cmd -> name , "sendkey" )) {
3017
3018
3019
char * sep = strrchr ( str , '-' );
if ( sep )
str = sep + 1 ;
3020
readline_set_completion_index ( cur_mon -> rs , strlen ( str ));
3021
3022
3023
for ( key = key_defs ; key -> name != NULL ; key ++ ) {
cmd_completion ( str , key -> name );
}
3024
3025
}
break ;
3026
3027
3028
3029
3030
3031
3032
3033
default :
break ;
}
}
for ( i = 0 ; i < nb_args ; i ++ )
qemu_free ( args [ i ]);
}
3034
static int monitor_can_read ( void * opaque )
3035
{
3036
3037
3038
Monitor * mon = opaque ;
return ( mon -> suspend_cnt == 0 ) ? 128 : 0 ;
3039
3040
}
3041
static void monitor_read ( void * opaque , const uint8_t * buf , int size )
3042
{
3043
Monitor * old_mon = cur_mon ;
3044
int i ;
3045
3046
3047
cur_mon = opaque ;
3048
3049
3050
3051
3052
3053
3054
3055
3056
if ( cur_mon -> rs ) {
for ( i = 0 ; i < size ; i ++ )
readline_handle_byte ( cur_mon -> rs , buf [ i ]);
} else {
if ( size == 0 || buf [ size - 1 ] != 0 )
monitor_printf ( cur_mon , "corrupted command \n " );
else
monitor_handle_command ( cur_mon , ( char * ) buf );
}
3057
3058
3059
cur_mon = old_mon ;
}
3060
3061
static void monitor_command_cb ( Monitor * mon , const char * cmdline , void * opaque )
3062
{
3063
monitor_suspend ( mon );
3064
monitor_handle_command ( mon , cmdline );
3065
monitor_resume ( mon );
3066
3067
}
3068
int monitor_suspend ( Monitor * mon )
3069
{
3070
3071
if ( ! mon -> rs )
return - ENOTTY ;
3072
mon -> suspend_cnt ++ ;
3073
return 0 ;
3074
3075
}
3076
void monitor_resume ( Monitor * mon )
3077
{
3078
3079
if ( ! mon -> rs )
return ;
3080
3081
if ( -- mon -> suspend_cnt == 0 )
readline_show_prompt ( mon -> rs );
3082
3083
}
3084
static void monitor_event ( void * opaque , int event )
ths
authored
18 years ago
3085
{
3086
3087
Monitor * mon = opaque ;
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
switch ( event ) {
case CHR_EVENT_MUX_IN :
readline_restart ( mon -> rs );
monitor_resume ( mon );
monitor_flush ( mon );
break ;
case CHR_EVENT_MUX_OUT :
if ( mon -> suspend_cnt == 0 )
monitor_printf ( mon , " \n " );
monitor_flush ( mon );
monitor_suspend ( mon );
break ;
ths
authored
18 years ago
3101
3102
3103
3104
3105
3106
3107
3108
case CHR_EVENT_RESET :
monitor_printf ( mon , "QEMU %s monitor - type 'help' for more "
"information \n " , QEMU_VERSION );
if ( mon -> chr -> focus == 0 )
readline_show_prompt ( mon -> rs );
break ;
}
ths
authored
18 years ago
3109
3110
}
3111
3112
3113
3114
3115
3116
3117
3118
3119
/*
* Local variables :
* c - indent - level : 4
* c - basic - offset : 4
* tab - width : 8
* End :
*/
3120
void monitor_init ( CharDriverState * chr , int flags )
3121
{
3122
static int is_first_init = 1 ;
3123
Monitor * mon ;
ths
authored
18 years ago
3124
3125
if ( is_first_init ) {
3126
key_timer = qemu_new_timer ( vm_clock , release_keys , NULL );
ths
authored
18 years ago
3127
3128
is_first_init = 0 ;
}
3129
3130
mon = qemu_mallocz ( sizeof ( * mon ));
ths
authored
18 years ago
3131
3132
mon -> chr = chr ;
3133
mon -> flags = flags ;
3134
3135
if ( mon -> chr -> focus != 0 )
mon -> suspend_cnt = 1 ; /* mux'ed monitors start suspended */
3136
3137
3138
3139
if ( flags & MONITOR_USE_READLINE ) {
mon -> rs = readline_init ( mon , monitor_find_completion );
monitor_read_command ( mon , 0 );
}
3140
3141
3142
qemu_chr_add_handlers ( chr , monitor_can_read , monitor_read , monitor_event ,
mon );
3143
3144
LIST_INSERT_HEAD ( & mon_list , mon , entry );
3145
if ( ! cur_mon || ( flags & MONITOR_IS_DEFAULT ))
3146
cur_mon = mon ;
3147
3148
}
3149
static void bdrv_password_cb ( Monitor * mon , const char * password , void * opaque )
3150
{
3151
3152
BlockDriverState * bs = opaque ;
int ret = 0 ;
3153
3154
if ( bdrv_set_key ( bs , password ) != 0 ) {
3155
monitor_printf ( mon , "invalid password \n " );
3156
ret = - EPERM ;
3157
}
3158
3159
if ( mon -> password_completion_cb )
mon -> password_completion_cb ( mon -> password_opaque , ret );
3160
3161
monitor_read_command ( mon , 1 );
3162
}
3163
3164
void monitor_read_bdrv_key_start ( Monitor * mon , BlockDriverState * bs ,
3165
3166
BlockDriverCompletionFunc * completion_cb ,
void * opaque )
3167
{
3168
3169
int err ;
3170
3171
3172
3173
3174
if ( ! bdrv_key_required ( bs )) {
if ( completion_cb )
completion_cb ( opaque , 0 );
return ;
}
3175
3176
3177
monitor_printf ( mon , "%s (%s) is encrypted. \n " , bdrv_get_device_name ( bs ),
bdrv_get_encrypted_filename ( bs ));
3178
3179
3180
mon -> password_completion_cb = completion_cb ;
mon -> password_opaque = opaque ;
3181
3182
3183
3184
3185
err = monitor_read_password ( mon , bdrv_password_cb , bs );
if ( err && completion_cb )
completion_cb ( opaque , err );
3186
}