Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
Xing Lin
qemu
Commits
6a00d601
Commit
6a00d601
authored
Nov 21, 2005
by
bellard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
SMP support
git-svn-id:
svn://svn.savannah.nongnu.org/qemu/trunk@1640
c046a42c-6fe2-441c-8c8c-71466251a162
parent
f0aca822
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
296 additions
and
138 deletions
+296
-138
cpu-defs.h
cpu-defs.h
+3
-2
cpu-exec.c
cpu-exec.c
+4
-0
disas.c
disas.c
+7
-3
exec-all.h
exec-all.h
+1
-1
exec.c
exec.c
+52
-52
gdbstub.c
gdbstub.c
+8
-5
monitor.c
monitor.c
+152
-38
vl.c
vl.c
+62
-37
vl.h
vl.h
+7
-0
No files found.
cpu-defs.h
View file @
6a00d601
...
...
@@ -96,6 +96,7 @@ typedef struct CPUTLBEntry {
#define CPU_COMMON \
struct TranslationBlock *current_tb;
/* currently executing TB */
\
int cpu_halted;
/* TRUE if cpu is halted (sleep mode) */
\
/* soft mmu support */
\
/* in order to avoid passing too many arguments to the memory \
write helpers, we store some rarely used information in the CPU \
...
...
@@ -115,9 +116,9 @@ typedef struct CPUTLBEntry {
int nb_breakpoints; \
int singlestep_enabled; \
\
void *next_cpu;
/* next CPU sharing TB cache */
\
int cpu_index;
/* CPU index (informative) */
\
/* user data */
\
void *opaque;
#endif
cpu-exec.c
View file @
6a00d601
...
...
@@ -251,6 +251,8 @@ int cpu_exec(CPUState *env1)
TranslationBlock
*
tb
;
uint8_t
*
tc_ptr
;
cpu_single_env
=
env1
;
/* first we save global registers */
saved_env
=
env
;
env
=
env1
;
...
...
@@ -755,6 +757,8 @@ int cpu_exec(CPUState *env1)
T2
=
saved_T2
;
#endif
env
=
saved_env
;
/* fail safe : never use cpu_single_env outside cpu_exec() */
cpu_single_env
=
NULL
;
return
ret
;
}
...
...
disas.c
View file @
6a00d601
...
...
@@ -138,6 +138,7 @@ print_insn_thumb1(bfd_vma pc, disassemble_info *info)
values:
i386 - nonzero means 16 bit code
arm - nonzero means thumb code
ppc - nonzero means little endian
other targets - unused
*/
void
target_disas
(
FILE
*
out
,
target_ulong
code
,
target_ulong
size
,
int
flags
)
...
...
@@ -177,7 +178,7 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
disasm_info
.
mach
=
bfd_mach_sparc_v9b
;
#endif
#elif defined(TARGET_PPC)
if
(
cpu_single_env
->
msr
[
MSR_LE
]
)
if
(
flags
)
disasm_info
.
endian
=
BFD_ENDIAN_LITTLE
;
#ifdef TARGET_PPC64
disasm_info
.
mach
=
bfd_mach_ppc64
;
...
...
@@ -314,6 +315,7 @@ void term_vprintf(const char *fmt, va_list ap);
void
term_printf
(
const
char
*
fmt
,
...);
static
int
monitor_disas_is_physical
;
static
CPUState
*
monitor_disas_env
;
static
int
monitor_read_memory
(
memaddr
,
myaddr
,
length
,
info
)
...
...
@@ -325,7 +327,7 @@ monitor_read_memory (memaddr, myaddr, length, info)
if
(
monitor_disas_is_physical
)
{
cpu_physical_memory_rw
(
memaddr
,
myaddr
,
length
,
0
);
}
else
{
cpu_memory_rw_debug
(
cpu_single
_env
,
memaddr
,
myaddr
,
length
,
0
);
cpu_memory_rw_debug
(
monitor_disas
_env
,
memaddr
,
myaddr
,
length
,
0
);
}
return
0
;
}
...
...
@@ -339,7 +341,8 @@ static int monitor_fprintf(FILE *stream, const char *fmt, ...)
return
0
;
}
void
monitor_disas
(
target_ulong
pc
,
int
nb_insn
,
int
is_physical
,
int
flags
)
void
monitor_disas
(
CPUState
*
env
,
target_ulong
pc
,
int
nb_insn
,
int
is_physical
,
int
flags
)
{
int
count
,
i
;
struct
disassemble_info
disasm_info
;
...
...
@@ -347,6 +350,7 @@ void monitor_disas(target_ulong pc, int nb_insn, int is_physical, int flags)
INIT_DISASSEMBLE_INFO
(
disasm_info
,
NULL
,
monitor_fprintf
);
monitor_disas_env
=
env
;
monitor_disas_is_physical
=
is_physical
;
disasm_info
.
read_memory_func
=
monitor_read_memory
;
...
...
exec-all.h
View file @
6a00d601
...
...
@@ -91,7 +91,7 @@ int cpu_restore_state_copy(struct TranslationBlock *tb,
CPUState
*
env
,
unsigned
long
searched_pc
,
void
*
puc
);
void
cpu_resume_from_signal
(
CPUState
*
env1
,
void
*
puc
);
void
cpu_exec_init
(
void
);
void
cpu_exec_init
(
CPUState
*
env
);
int
page_unprotect
(
unsigned
long
address
,
unsigned
long
pc
,
void
*
puc
);
void
tb_invalidate_phys_page_range
(
target_ulong
start
,
target_ulong
end
,
int
is_cpu_write_access
);
...
...
exec.c
View file @
6a00d601
...
...
@@ -74,6 +74,11 @@ int phys_ram_fd;
uint8_t
*
phys_ram_base
;
uint8_t
*
phys_ram_dirty
;
CPUState
*
first_cpu
;
/* current CPU in the current thread. It is only valid inside
cpu_exec() */
CPUState
*
cpu_single_env
;
typedef
struct
PageDesc
{
/* list of TBs intersecting this ram page */
TranslationBlock
*
first_tb
;
...
...
@@ -233,19 +238,30 @@ static inline PhysPageDesc *phys_page_find(target_phys_addr_t index)
}
#if !defined(CONFIG_USER_ONLY)
static
void
tlb_protect_code
(
CPUState
*
env
,
ram_addr_t
ram_addr
,
target_ulong
vaddr
);
static
void
tlb_protect_code
(
ram_addr_t
ram_addr
);
static
void
tlb_unprotect_code_phys
(
CPUState
*
env
,
ram_addr_t
ram_addr
,
target_ulong
vaddr
);
#endif
void
cpu_exec_init
(
void
)
void
cpu_exec_init
(
CPUState
*
env
)
{
CPUState
**
penv
;
int
cpu_index
;
if
(
!
code_gen_ptr
)
{
code_gen_ptr
=
code_gen_buffer
;
page_init
();
io_mem_init
();
}
env
->
next_cpu
=
NULL
;
penv
=
&
first_cpu
;
cpu_index
=
0
;
while
(
*
penv
!=
NULL
)
{
penv
=
(
CPUState
**
)
&
(
*
penv
)
->
next_cpu
;
cpu_index
++
;
}
env
->
cpu_index
=
cpu_index
;
*
penv
=
env
;
}
static
inline
void
invalidate_page_bitmap
(
PageDesc
*
p
)
...
...
@@ -277,8 +293,9 @@ static void page_flush_tb(void)
/* flush all the translation blocks */
/* XXX: tb_flush is currently not thread safe */
void
tb_flush
(
CPUState
*
env
)
void
tb_flush
(
CPUState
*
env
1
)
{
CPUState
*
env
;
#if defined(DEBUG_FLUSH)
printf
(
"qemu: flush code_size=%d nb_tbs=%d avg_tb_size=%d
\n
"
,
code_gen_ptr
-
code_gen_buffer
,
...
...
@@ -286,7 +303,10 @@ void tb_flush(CPUState *env)
nb_tbs
>
0
?
(
code_gen_ptr
-
code_gen_buffer
)
/
nb_tbs
:
0
);
#endif
nb_tbs
=
0
;
memset
(
env
->
tb_jmp_cache
,
0
,
TB_JMP_CACHE_SIZE
*
sizeof
(
void
*
));
for
(
env
=
first_cpu
;
env
!=
NULL
;
env
=
env
->
next_cpu
)
{
memset
(
env
->
tb_jmp_cache
,
0
,
TB_JMP_CACHE_SIZE
*
sizeof
(
void
*
));
}
memset
(
tb_phys_hash
,
0
,
CODE_GEN_PHYS_HASH_SIZE
*
sizeof
(
void
*
));
page_flush_tb
();
...
...
@@ -424,6 +444,7 @@ static inline void tb_reset_jump(TranslationBlock *tb, int n)
static
inline
void
tb_phys_invalidate
(
TranslationBlock
*
tb
,
unsigned
int
page_addr
)
{
CPUState
*
env
;
PageDesc
*
p
;
unsigned
int
h
,
n1
;
target_ulong
phys_pc
;
...
...
@@ -451,7 +472,10 @@ static inline void tb_phys_invalidate(TranslationBlock *tb, unsigned int page_ad
/* remove the TB from the hash list */
h
=
tb_jmp_cache_hash_func
(
tb
->
pc
);
cpu_single_env
->
tb_jmp_cache
[
h
]
=
NULL
;
for
(
env
=
first_cpu
;
env
!=
NULL
;
env
=
env
->
next_cpu
)
{
if
(
env
->
tb_jmp_cache
[
h
]
==
tb
)
env
->
tb_jmp_cache
[
h
]
=
NULL
;
}
/* suppress this TB from the two jump lists */
tb_jmp_remove
(
tb
,
0
);
...
...
@@ -818,10 +842,7 @@ static inline void tb_alloc_page(TranslationBlock *tb,
protected. So we handle the case where only the first TB is
allocated in a physical page */
if
(
!
last_first_tb
)
{
target_ulong
virt_addr
;
virt_addr
=
(
tb
->
pc
&
TARGET_PAGE_MASK
)
+
(
n
<<
TARGET_PAGE_BITS
);
tlb_protect_code
(
cpu_single_env
,
page_addr
,
virt_addr
);
tlb_protect_code
(
page_addr
);
}
#endif
...
...
@@ -1246,40 +1267,13 @@ void tlb_flush_page(CPUState *env, target_ulong addr)
#endif
}
static
inline
void
tlb_protect_code1
(
CPUTLBEntry
*
tlb_entry
,
target_ulong
addr
)
{
if
(
addr
==
(
tlb_entry
->
address
&
(
TARGET_PAGE_MASK
|
TLB_INVALID_MASK
))
&&
(
tlb_entry
->
address
&
~
TARGET_PAGE_MASK
)
==
IO_MEM_RAM
)
{
tlb_entry
->
address
=
(
tlb_entry
->
address
&
TARGET_PAGE_MASK
)
|
IO_MEM_NOTDIRTY
;
}
}
/* update the TLBs so that writes to code in the virtual page 'addr'
can be detected */
static
void
tlb_protect_code
(
CPUState
*
env
,
ram_addr_t
ram_addr
,
target_ulong
vaddr
)
static
void
tlb_protect_code
(
ram_addr_t
ram_addr
)
{
int
i
;
vaddr
&=
TARGET_PAGE_MASK
;
i
=
(
vaddr
>>
TARGET_PAGE_BITS
)
&
(
CPU_TLB_SIZE
-
1
);
tlb_protect_code1
(
&
env
->
tlb_write
[
0
][
i
],
vaddr
);
tlb_protect_code1
(
&
env
->
tlb_write
[
1
][
i
],
vaddr
);
#ifdef USE_KQEMU
if
(
env
->
kqemu_enabled
)
{
kqemu_set_notdirty
(
env
,
ram_addr
);
}
#endif
phys_ram_dirty
[
ram_addr
>>
TARGET_PAGE_BITS
]
&=
~
CODE_DIRTY_FLAG
;
#if !defined(CONFIG_SOFTMMU)
/* NOTE: as we generated the code for this page, it is already at
least readable */
if
(
vaddr
<
MMAP_AREA_END
)
mprotect
((
void
*
)
vaddr
,
TARGET_PAGE_SIZE
,
PROT_READ
);
#endif
cpu_physical_memory_reset_dirty
(
ram_addr
,
ram_addr
+
TARGET_PAGE_SIZE
,
CODE_DIRTY_FLAG
);
}
/* update the TLB so that writes in physical page 'phys_addr' are no longer
...
...
@@ -1317,8 +1311,9 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
if
(
length
==
0
)
return
;
len
=
length
>>
TARGET_PAGE_BITS
;
env
=
cpu_single_env
;
#ifdef USE_KQEMU
/* XXX: should not depend on cpu context */
env
=
first_cpu
;
if
(
env
->
kqemu_enabled
)
{
ram_addr_t
addr
;
addr
=
start
;
...
...
@@ -1336,10 +1331,12 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
/* we modify the TLB cache so that the dirty bit will be set again
when accessing the range */
start1
=
start
+
(
unsigned
long
)
phys_ram_base
;
for
(
i
=
0
;
i
<
CPU_TLB_SIZE
;
i
++
)
tlb_reset_dirty_range
(
&
env
->
tlb_write
[
0
][
i
],
start1
,
length
);
for
(
i
=
0
;
i
<
CPU_TLB_SIZE
;
i
++
)
tlb_reset_dirty_range
(
&
env
->
tlb_write
[
1
][
i
],
start1
,
length
);
for
(
env
=
first_cpu
;
env
!=
NULL
;
env
=
env
->
next_cpu
)
{
for
(
i
=
0
;
i
<
CPU_TLB_SIZE
;
i
++
)
tlb_reset_dirty_range
(
&
env
->
tlb_write
[
0
][
i
],
start1
,
length
);
for
(
i
=
0
;
i
<
CPU_TLB_SIZE
;
i
++
)
tlb_reset_dirty_range
(
&
env
->
tlb_write
[
1
][
i
],
start1
,
length
);
}
#if !defined(CONFIG_SOFTMMU)
/* XXX: this is expensive */
...
...
@@ -1407,9 +1404,9 @@ static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry,
/* update the TLB corresponding to virtual page vaddr and phys addr
addr so that it is no longer dirty */
static
inline
void
tlb_set_dirty
(
unsigned
long
addr
,
target_ulong
vaddr
)
static
inline
void
tlb_set_dirty
(
CPUState
*
env
,
unsigned
long
addr
,
target_ulong
vaddr
)
{
CPUState
*
env
=
cpu_single_env
;
int
i
;
addr
&=
TARGET_PAGE_MASK
;
...
...
@@ -1723,7 +1720,8 @@ void page_unprotect_range(uint8_t *data, unsigned long data_size)
}
}
static
inline
void
tlb_set_dirty
(
unsigned
long
addr
,
target_ulong
vaddr
)
static
inline
void
tlb_set_dirty
(
CPUState
*
env
,
unsigned
long
addr
,
target_ulong
vaddr
)
{
}
#endif
/* defined(CONFIG_USER_ONLY) */
...
...
@@ -1787,7 +1785,7 @@ static void notdirty_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t
/* we remove the notdirty callback only if the code has been
flushed */
if
(
dirty_flags
==
0xff
)
tlb_set_dirty
(
addr
,
cpu_single_env
->
mem_write_vaddr
);
tlb_set_dirty
(
cpu_single_env
,
addr
,
cpu_single_env
->
mem_write_vaddr
);
}
static
void
notdirty_mem_writew
(
void
*
opaque
,
target_phys_addr_t
addr
,
uint32_t
val
)
...
...
@@ -1808,7 +1806,7 @@ static void notdirty_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t
/* we remove the notdirty callback only if the code has been
flushed */
if
(
dirty_flags
==
0xff
)
tlb_set_dirty
(
addr
,
cpu_single_env
->
mem_write_vaddr
);
tlb_set_dirty
(
cpu_single_env
,
addr
,
cpu_single_env
->
mem_write_vaddr
);
}
static
void
notdirty_mem_writel
(
void
*
opaque
,
target_phys_addr_t
addr
,
uint32_t
val
)
...
...
@@ -1829,7 +1827,7 @@ static void notdirty_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t
/* we remove the notdirty callback only if the code has been
flushed */
if
(
dirty_flags
==
0xff
)
tlb_set_dirty
(
addr
,
cpu_single_env
->
mem_write_vaddr
);
tlb_set_dirty
(
cpu_single_env
,
addr
,
cpu_single_env
->
mem_write_vaddr
);
}
static
CPUReadMemoryFunc
*
error_mem_read
[
3
]
=
{
...
...
@@ -1953,6 +1951,8 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
if
(
is_write
)
{
if
((
pd
&
~
TARGET_PAGE_MASK
)
!=
IO_MEM_RAM
)
{
io_index
=
(
pd
>>
IO_MEM_SHIFT
)
&
(
IO_MEM_NB_ENTRIES
-
1
);
/* XXX: could force cpu_single_env to NULL to avoid
potential bugs */
if
(
l
>=
4
&&
((
addr
&
3
)
==
0
))
{
/* 32 bit write access */
val
=
ldl_p
(
buf
);
...
...
gdbstub.c
View file @
6a00d601
...
...
@@ -47,6 +47,7 @@ enum RSState {
static
int
gdbserver_fd
=
-
1
;
typedef
struct
GDBState
{
CPUState
*
env
;
/* current CPU */
enum
RSState
state
;
/* parsing state */
int
fd
;
char
line_buf
[
4096
];
...
...
@@ -576,10 +577,10 @@ static void gdb_vm_stopped(void *opaque, int reason)
int
ret
;
/* disable single step if it was enable */
cpu_single_step
(
cpu_single_
env
,
0
);
cpu_single_step
(
s
->
env
,
0
);
if
(
reason
==
EXCP_DEBUG
)
{
tb_flush
(
cpu_single_
env
);
tb_flush
(
s
->
env
);
ret
=
SIGTRAP
;
}
else
...
...
@@ -589,8 +590,9 @@ static void gdb_vm_stopped(void *opaque, int reason)
}
#endif
static
void
gdb_read_byte
(
GDBState
*
s
,
CPUState
*
env
,
int
ch
)
static
void
gdb_read_byte
(
GDBState
*
s
,
int
ch
)
{
CPUState
*
env
=
s
->
env
;
int
i
,
csum
;
char
reply
[
1
];
...
...
@@ -676,7 +678,7 @@ gdb_handlesig (CPUState *env, int sig)
int
i
;
for
(
i
=
0
;
i
<
n
;
i
++
)
gdb_read_byte
(
s
,
env
,
buf
[
i
]);
gdb_read_byte
(
s
,
buf
[
i
]);
}
else
if
(
n
==
0
||
errno
!=
EAGAIN
)
{
...
...
@@ -721,7 +723,7 @@ static void gdb_read(void *opaque)
vm_start
();
}
else
{
for
(
i
=
0
;
i
<
size
;
i
++
)
gdb_read_byte
(
s
,
cpu_single_env
,
buf
[
i
]);
gdb_read_byte
(
s
,
buf
[
i
]);
}
}
...
...
@@ -759,6 +761,7 @@ static void gdb_accept(void *opaque)
return
;
}
#endif
s
->
env
=
first_cpu
;
/* XXX: allow to change CPU */
s
->
fd
=
fd
;
fcntl
(
fd
,
F_SETFL
,
O_NONBLOCK
);
...
...
monitor.c
View file @
6a00d601
...
...
@@ -64,6 +64,8 @@ static int term_outbuf_index;
static
void
monitor_start_input
(
void
);
CPUState
*
mon_cpu
=
NULL
;
void
term_flush
(
void
)
{
if
(
term_outbuf_index
>
0
)
{
...
...
@@ -201,17 +203,69 @@ static void do_info_block(void)
bdrv_info
();
}
/* get the current CPU defined by the user */
int
mon_set_cpu
(
int
cpu_index
)
{
CPUState
*
env
;
for
(
env
=
first_cpu
;
env
!=
NULL
;
env
=
env
->
next_cpu
)
{
if
(
env
->
cpu_index
==
cpu_index
)
{
mon_cpu
=
env
;
return
0
;
}
}
return
-
1
;
}
CPUState
*
mon_get_cpu
(
void
)
{
if
(
!
mon_cpu
)
{
mon_set_cpu
(
0
);
}
return
mon_cpu
;
}
static
void
do_info_registers
(
void
)
{
CPUState
*
env
;
env
=
mon_get_cpu
();
if
(
!
env
)
return
;
#ifdef TARGET_I386
cpu_dump_state
(
cpu_single_
env
,
NULL
,
monitor_fprintf
,
cpu_dump_state
(
env
,
NULL
,
monitor_fprintf
,
X86_DUMP_FPU
);
#else
cpu_dump_state
(
cpu_single_
env
,
NULL
,
monitor_fprintf
,
cpu_dump_state
(
env
,
NULL
,
monitor_fprintf
,
0
);
#endif
}
static
void
do_info_cpus
(
void
)
{
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
)
{
term_printf
(
"%c CPU #%d:"
,
(
env
==
mon_cpu
)
?
'*'
:
' '
,
env
->
cpu_index
);
#if defined(TARGET_I386)
term_printf
(
" pc=0x"
TARGET_FMT_lx
,
env
->
eip
+
env
->
segs
[
R_CS
].
base
);
if
(
env
->
cpu_halted
)
term_printf
(
" (halted)"
);
#endif
term_printf
(
"
\n
"
);
}
}
static
void
do_cpu_set
(
int
index
)
{
if
(
mon_set_cpu
(
index
)
<
0
)
term_printf
(
"Invalid CPU index
\n
"
);
}
static
void
do_info_jit
(
void
)
{
dump_exec_info
(
NULL
,
monitor_fprintf
);
...
...
@@ -381,6 +435,7 @@ static void term_printc(int c)
static
void
memory_dump
(
int
count
,
int
format
,
int
wsize
,
target_ulong
addr
,
int
is_physical
)
{
CPUState
*
env
;
int
nb_per_line
,
l
,
line_size
,
i
,
max_digits
,
len
;
uint8_t
buf
[
16
];
uint64_t
v
;
...
...
@@ -388,19 +443,22 @@ static void memory_dump(int count, int format, int wsize,
if
(
format
==
'i'
)
{
int
flags
;
flags
=
0
;
env
=
mon_get_cpu
();
if
(
!
env
&&
!
is_physical
)
return
;
#ifdef TARGET_I386
if
(
wsize
==
2
)
{
flags
=
1
;
}
else
if
(
wsize
==
4
)
{
flags
=
0
;
}
else
{
/* as default we use the current CS size */
/* as default we use the current CS size */
flags
=
0
;
if
(
!
(
cpu_single_
env
->
segs
[
R_CS
].
flags
&
DESC_B_MASK
))
if
(
env
&&
!
(
env
->
segs
[
R_CS
].
flags
&
DESC_B_MASK
))
flags
=
1
;
}
#endif
monitor_disas
(
addr
,
count
,
is_physical
,
flags
);
monitor_disas
(
env
,
addr
,
count
,
is_physical
,
flags
);
return
;
}
...
...
@@ -437,7 +495,10 @@ static void memory_dump(int count, int format, int wsize,
if
(
is_physical
)
{
cpu_physical_memory_rw
(
addr
,
buf
,
l
,
0
);
}
else
{
cpu_memory_rw_debug
(
cpu_single_env
,
addr
,
buf
,
l
,
0
);
env
=
mon_get_cpu
();
if
(
!
env
)
break
;
cpu_memory_rw_debug
(
env
,
addr
,
buf
,
l
,
0
);
}
i
=
0
;
while
(
i
<
l
)
{
...
...
@@ -776,10 +837,14 @@ static void print_pte(uint32_t addr, uint32_t pte, uint32_t mask)
static
void
tlb_info
(
void
)
{
CPUState
*
env
=
cpu_single_env
;
CPUState
*
env
;
int
l1
,
l2
;
uint32_t
pgd
,
pde
,
pte
;
env
=
mon_get_cpu
();
if
(
!
env
)
return
;
if
(
!
(
env
->
cr
[
0
]
&
CR0_PG_MASK
))
{
term_printf
(
"PG disabled
\n
"
);
return
;
...
...
@@ -830,10 +895,14 @@ static void mem_print(uint32_t *pstart, int *plast_prot,
static
void
mem_info
(
void
)
{
CPUState
*
env
=
cpu_single_env
;
CPUState
*
env
;
int
l1
,
l2
,
prot
,
last_prot
;
uint32_t
pgd
,
pde
,
pte
,
start
,
end
;
env
=
mon_get_cpu
();
if
(
!
env
)
return
;
if
(
!
(
env
->
cr
[
0
]
&
CR0_PG_MASK
))
{
term_printf
(
"PG disabled
\n
"
);
return
;
...
...
@@ -874,10 +943,15 @@ static void mem_info(void)
static
void
do_info_kqemu
(
void
)
{
#ifdef USE_KQEMU
CPUState
*
env
;
int
val
;
val
=
0
;
if
(
cpu_single_env
)
val
=
cpu_single_env
->
kqemu_enabled
;
env
=
mon_get_cpu
();
if
(
!
env
)
{
term_printf
(
"No cpu initialized yet"
);
return
;
}
val
=
env
->
kqemu_enabled
;
term_printf
(
"kqemu is %s
\n
"
,
val
?
"enabled"
:
"disabled"
);
#else
term_printf
(
"kqemu support is not compiled
\n
"
);
...
...
@@ -934,6 +1008,8 @@ static term_cmd_t term_cmds[] = {
"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'"
},
{
"cpu"
,
"i"
,
do_cpu_set
,
"index"
,
"set the default CPU"
},
{
NULL
,
NULL
,
},
};
...
...
@@ -946,6 +1022,8 @@ static term_cmd_t info_cmds[] = {
""
,
"show the block devices"
},
{
"registers"
,
""
,
do_info_registers
,
""
,
"show the cpu registers"
},
{
"cpus"
,
""
,
do_info_cpus
,
""
,
"show infos for each CPU"
},
{
"history"
,
""
,
do_info_history
,
""
,
"show the command line history"
,
},
{
"irq"
,
""
,
irq_info
,
...
...
@@ -989,63 +1067,85 @@ typedef struct MonitorDef {
#if defined(TARGET_I386)
static
target_long
monitor_get_pc
(
struct
MonitorDef
*
md
,
int
val
)
{
return
cpu_single_env
->
eip
+
cpu_single_env
->
segs
[
R_CS
].
base
;
CPUState
*
env
=
mon_get_cpu
();
if
(
!
env
)
return
0
;
return
env
->
eip
+
env
->
segs
[
R_CS
].
base
;
}
#endif
#if defined(TARGET_PPC)
static
target_long
monitor_get_ccr
(
struct
MonitorDef
*
md
,
int
val
)
{
CPUState
*
env
=
mon_get_cpu
();
unsigned
int
u
;
int
i
;
if
(
!
env
)
return
0
;
u
=
0
;
for
(
i
=
0
;
i
<
8
;
i
++
)
u
|=
cpu_single_
env
->
crf
[
i
]
<<
(
32
-
(
4
*
i
));
u
|=
env
->
crf
[
i
]
<<
(
32
-
(
4
*
i
));
return
u
;
}
static
target_long
monitor_get_msr
(
struct
MonitorDef
*
md
,
int
val
)
{
return
(
cpu_single_env
->
msr
[
MSR_POW
]
<<
MSR_POW
)
|
(
cpu_single_env
->
msr
[
MSR_ILE
]
<<
MSR_ILE
)
|
(
cpu_single_env
->
msr
[
MSR_EE
]
<<
MSR_EE
)
|
(
cpu_single_env
->
msr
[
MSR_PR
]
<<
MSR_PR
)
|
(
cpu_single_env
->
msr
[
MSR_FP
]
<<
MSR_FP
)
|
(
cpu_single_env
->
msr
[
MSR_ME
]
<<
MSR_ME
)
|
(
cpu_single_env
->
msr
[
MSR_FE0
]
<<
MSR_FE0
)
|
(
cpu_single_env
->
msr
[
MSR_SE
]
<<
MSR_SE
)
|
(
cpu_single_env
->
msr
[
MSR_BE
]
<<
MSR_BE
)
|
(
cpu_single_env
->
msr
[
MSR_FE1
]
<<
MSR_FE1
)
|
(
cpu_single_env
->
msr
[
MSR_IP
]
<<
MSR_IP
)
|
(
cpu_single_env
->
msr
[
MSR_IR
]
<<
MSR_IR
)
|
(
cpu_single_env
->
msr
[
MSR_DR
]
<<
MSR_DR
)
|
(
cpu_single_env
->
msr
[
MSR_RI
]
<<
MSR_RI
)
|
(
cpu_single_env
->
msr
[
MSR_LE
]
<<
MSR_LE
);
CPUState
*
env
=
mon_get_cpu
();
if
(
!
env
)
return
0
;
return
(
env
->
msr
[
MSR_POW
]
<<
MSR_POW
)
|
(
env
->
msr
[
MSR_ILE
]
<<
MSR_ILE
)
|
(
env
->
msr
[
MSR_EE
]
<<
MSR_EE
)
|
(
env
->
msr
[
MSR_PR
]
<<
MSR_PR
)
|
(
env
->
msr
[
MSR_FP
]
<<
MSR_FP
)
|
(
env
->
msr
[
MSR_ME
]
<<
MSR_ME
)
|
(
env
->
msr
[
MSR_FE0
]
<<
MSR_FE0
)
|
(
env
->
msr
[
MSR_SE
]
<<
MSR_SE
)
|
(
env
->
msr
[
MSR_BE
]
<<
MSR_BE
)
|
(
env
->
msr
[
MSR_FE1
]
<<
MSR_FE1
)
|
(
env
->
msr
[
MSR_IP
]
<<
MSR_IP
)
|
(
env
->
msr
[
MSR_IR
]
<<
MSR_IR
)
|
(
env
->
msr
[
MSR_DR
]
<<
MSR_DR
)
|
(
env
->
msr
[
MSR_RI
]
<<
MSR_RI
)
|
(
env
->
msr
[
MSR_LE
]
<<
MSR_LE
);
}
static
target_long
monitor_get_xer
(
struct
MonitorDef
*
md
,
int
val
)
{