Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
6a00d601
Q
qemu
项目概览
openeuler
/
qemu
通知
10
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Q
qemu
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
6a00d601
编写于
11月 21, 2005
作者:
B
bellard
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
SMP support
git-svn-id:
svn://svn.savannah.nongnu.org/qemu/trunk@1640
c046a42c-6fe2-441c-8c8c-71466251a162
上级
f0aca822
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
296 addition
and
138 deletion
+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
未找到文件。
cpu-defs.h
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
浏览文件 @
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
)
{
return
(
cpu_single_env
->
xer
[
XER_SO
]
<<
XER_SO
)
|
(
cpu_single_env
->
xer
[
XER_OV
]
<<
XER_OV
)
|
(
cpu_single_env
->
xer
[
XER_CA
]
<<
XER_CA
)
|
(
cpu_single_env
->
xer
[
XER_BC
]
<<
XER_BC
);
CPUState
*
env
=
mon_get_cpu
();
if
(
!
env
)
return
0
;
return
(
env
->
xer
[
XER_SO
]
<<
XER_SO
)
|
(
env
->
xer
[
XER_OV
]
<<
XER_OV
)
|
(
env
->
xer
[
XER_CA
]
<<
XER_CA
)
|
(
env
->
xer
[
XER_BC
]
<<
XER_BC
);
}
static
target_long
monitor_get_decr
(
struct
MonitorDef
*
md
,
int
val
)
{
return
cpu_ppc_load_decr
(
cpu_single_env
);
CPUState
*
env
=
mon_get_cpu
();
if
(
!
env
)
return
0
;
return
cpu_ppc_load_decr
(
env
);
}
static
target_long
monitor_get_tbu
(
struct
MonitorDef
*
md
,
int
val
)
{
return
cpu_ppc_load_tbu
(
cpu_single_env
);
CPUState
*
env
=
mon_get_cpu
();
if
(
!
env
)
return
0
;
return
cpu_ppc_load_tbu
(
env
);
}
static
target_long
monitor_get_tbl
(
struct
MonitorDef
*
md
,
int
val
)
{
return
cpu_ppc_load_tbl
(
cpu_single_env
);
CPUState
*
env
=
mon_get_cpu
();
if
(
!
env
)
return
0
;
return
cpu_ppc_load_tbl
(
env
);
}
#endif
...
...
@@ -1053,13 +1153,19 @@ static target_long monitor_get_tbl (struct MonitorDef *md, int val)
#ifndef TARGET_SPARC64
static
target_long
monitor_get_psr
(
struct
MonitorDef
*
md
,
int
val
)
{
return
GET_PSR
(
cpu_single_env
);
CPUState
*
env
=
mon_get_cpu
();
if
(
!
env
)
return
0
;
return
GET_PSR
(
env
);
}
#endif
static
target_long
monitor_get_reg
(
struct
MonitorDef
*
md
,
int
val
)
{
return
cpu_single_env
->
regwptr
[
val
];
CPUState
*
env
=
mon_get_cpu
();
if
(
!
env
)
return
0
;
return
env
->
regwptr
[
val
];
}
#endif
...
...
@@ -1269,6 +1375,7 @@ static void expr_error(const char *fmt)
longjmp
(
expr_env
,
1
);
}
/* return 0 if OK, -1 if not found, -2 if no CPU defined */
static
int
get_monitor_def
(
target_long
*
pval
,
const
char
*
name
)
{
MonitorDef
*
md
;
...
...
@@ -1279,7 +1386,10 @@ static int get_monitor_def(target_long *pval, const char *name)
if
(
md
->
get_value
)
{
*
pval
=
md
->
get_value
(
md
,
md
->
offset
);
}
else
{
ptr
=
(
uint8_t
*
)
cpu_single_env
+
md
->
offset
;
CPUState
*
env
=
mon_get_cpu
();
if
(
!
env
)
return
-
2
;
ptr
=
(
uint8_t
*
)
env
+
md
->
offset
;
switch
(
md
->
type
)
{
case
MD_I32
:
*
pval
=
*
(
int32_t
*
)
ptr
;
...
...
@@ -1313,6 +1423,7 @@ static target_long expr_unary(void)
{
target_long
n
;
char
*
p
;
int
ret
;
switch
(
*
pch
)
{
case
'+'
:
...
...
@@ -1362,8 +1473,11 @@ static target_long expr_unary(void)
while
(
isspace
(
*
pch
))
pch
++
;
*
q
=
0
;
if
(
get_monitor_def
(
&
n
,
buf
))
ret
=
get_monitor_def
(
&
n
,
buf
);
if
(
ret
==
-
1
)
expr_error
(
"unknown register"
);
else
if
(
ret
==
-
2
)
expr_error
(
"no cpu defined"
);
}
break
;
case
'\0'
:
...
...
vl.c
浏览文件 @
6a00d601
...
...
@@ -83,8 +83,6 @@
#include "exec-all.h"
//#define DO_TB_FLUSH
#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
//#define DEBUG_UNUSED_IOPORT
...
...
@@ -109,8 +107,6 @@
const
char
*
bios_dir
=
CONFIG_QEMU_SHAREDIR
;
char
phys_ram_file
[
1024
];
CPUState
*
global_env
;
CPUState
*
cpu_single_env
;
void
*
ioport_opaque
[
MAX_IOPORTS
];
IOPortReadFunc
*
ioport_read_table
[
3
][
MAX_IOPORTS
];
IOPortWriteFunc
*
ioport_write_table
[
3
][
MAX_IOPORTS
];
...
...
@@ -156,6 +152,7 @@ int usb_enabled = 0;
USBPort
*
vm_usb_ports
[
MAX_VM_USB_PORTS
];
USBDevice
*
vm_usb_hub
;
static
VLANState
*
first_vlan
;
int
smp_cpus
=
1
;
/***********************************************************/
/* x86 ISA bus support */
...
...
@@ -427,16 +424,20 @@ int cpu_inl(CPUState *env, int addr)
void
hw_error
(
const
char
*
fmt
,
...)
{
va_list
ap
;
CPUState
*
env
;
va_start
(
ap
,
fmt
);
fprintf
(
stderr
,
"qemu: hardware error: "
);
vfprintf
(
stderr
,
fmt
,
ap
);
fprintf
(
stderr
,
"
\n
"
);
for
(
env
=
first_cpu
;
env
!=
NULL
;
env
=
env
->
next_cpu
)
{
fprintf
(
stderr
,
"CPU #%d:
\n
"
,
env
->
cpu_index
);
#ifdef TARGET_I386
cpu_dump_state
(
global_env
,
stderr
,
fprintf
,
X86_DUMP_FPU
|
X86_DUMP_CCOP
);
cpu_dump_state
(
env
,
stderr
,
fprintf
,
X86_DUMP_FPU
);
#else
cpu_dump_state
(
global_
env
,
stderr
,
fprintf
,
0
);
cpu_dump_state
(
env
,
stderr
,
fprintf
,
0
);
#endif
}
va_end
(
ap
);
abort
();
}
...
...
@@ -879,13 +880,16 @@ static void host_alarm_handler(int host_signum)
qemu_get_clock
(
vm_clock
))
||
qemu_timer_expired
(
active_timers
[
QEMU_TIMER_REALTIME
],
qemu_get_clock
(
rt_clock
)))
{
/* stop the cpu because a timer occured */
cpu_interrupt
(
global_env
,
CPU_INTERRUPT_EXIT
);
CPUState
*
env
=
cpu_single_env
;
if
(
env
)
{
/* stop the currently executing cpu because a timer occured */
cpu_interrupt
(
env
,
CPU_INTERRUPT_EXIT
);
#ifdef USE_KQEMU
if
(
global_
env
->
kqemu_enabled
)
{
kqemu_cpu_interrupt
(
global_
env
);
}
if
(
env
->
kqemu_enabled
)
{
kqemu_cpu_interrupt
(
env
);
}
#endif
}
}
}
...
...
@@ -2970,9 +2974,6 @@ int qemu_loadvm(const char *filename)
goto
the_end
;
}
for
(;;)
{
#if defined (DO_TB_FLUSH)
tb_flush
(
global_env
);
#endif
len
=
qemu_get_byte
(
f
);
if
(
feof
(
f
))
break
;
...
...
@@ -3583,27 +3584,22 @@ void qemu_system_reset(void)
void
qemu_system_reset_request
(
void
)
{
reset_requested
=
1
;
cpu_interrupt
(
cpu_single_env
,
CPU_INTERRUPT_EXIT
);
if
(
cpu_single_env
)
cpu_interrupt
(
cpu_single_env
,
CPU_INTERRUPT_EXIT
);
}
void
qemu_system_shutdown_request
(
void
)
{
shutdown_requested
=
1
;
cpu_interrupt
(
cpu_single_env
,
CPU_INTERRUPT_EXIT
);
if
(
cpu_single_env
)
cpu_interrupt
(
cpu_single_env
,
CPU_INTERRUPT_EXIT
);
}
void
qemu_system_powerdown_request
(
void
)
{
powerdown_requested
=
1
;
cpu_interrupt
(
cpu_single_env
,
CPU_INTERRUPT_EXIT
);
}
static
void
main_cpu_reset
(
void
*
opaque
)
{
#if defined(TARGET_I386) || defined(TARGET_SPARC)
CPUState
*
env
=
opaque
;
cpu_reset
(
env
);
#endif
if
(
cpu_single_env
)
cpu_interrupt
(
cpu_single_env
,
CPU_INTERRUPT_EXIT
);
}
void
main_loop_wait
(
int
timeout
)
...
...
@@ -3684,14 +3680,42 @@ void main_loop_wait(int timeout)
qemu_get_clock
(
rt_clock
));
}
static
CPUState
*
cur_cpu
;
static
CPUState
*
find_next_cpu
(
void
)
{
CPUState
*
env
;
env
=
cur_cpu
;
for
(;;)
{
/* get next cpu */
env
=
env
->
next_cpu
;
if
(
!
env
)
env
=
first_cpu
;
if
(
!
env
->
cpu_halted
)
break
;
/* all CPUs are halted ? */
if
(
env
==
cur_cpu
)
return
NULL
;
}
cur_cpu
=
env
;
return
env
;
}
int
main_loop
(
void
)
{
int
ret
,
timeout
;
CPUState
*
env
=
global_env
;
CPUState
*
env
;
cur_cpu
=
first_cpu
;
for
(;;)
{
if
(
vm_running
)
{
ret
=
cpu_exec
(
env
);
/* find next cpu to run */
/* XXX: handle HLT correctly */
env
=
find_next_cpu
();
if
(
!
env
)
ret
=
EXCP_HLT
;
else
ret
=
cpu_exec
(
env
);
if
(
shutdown_requested
)
{
ret
=
EXCP_INTERRUPT
;
break
;
...
...
@@ -3774,7 +3798,7 @@ void help(void)
" connect the host TAP network interface to VLAN 'n' and use
\n
"
" the network script 'file' (default=%s);
\n
"
" use 'fd=h' to connect to an already opened TAP interface
\n
"
"-net socket[,vlan=n][,fd=
x
][,listen=[host]:port][,connect=host:port]
\n
"
"-net socket[,vlan=n][,fd=
h
][,listen=[host]:port][,connect=host:port]
\n
"
" connect the vlan 'n' to another VLAN using a socket connection
\n
"
#endif
"-net none use it alone to have zero network devices; if no -net option
\n
"
...
...
@@ -3899,6 +3923,7 @@ enum {
QEMU_OPTION_win2k_hack
,
QEMU_OPTION_usb
,
QEMU_OPTION_usbdevice
,
QEMU_OPTION_smp
,
};
typedef
struct
QEMUOption
{
...
...
@@ -3965,6 +3990,7 @@ const QEMUOption qemu_options[] = {
{
"pidfile"
,
HAS_ARG
,
QEMU_OPTION_pidfile
},
{
"win2k-hack"
,
0
,
QEMU_OPTION_win2k_hack
},
{
"usbdevice"
,
HAS_ARG
,
QEMU_OPTION_usbdevice
},
{
"smp"
,
HAS_ARG
,
QEMU_OPTION_smp
},
/* temporary options */
{
"usb"
,
0
,
QEMU_OPTION_usb
},
...
...
@@ -4120,7 +4146,6 @@ int main(int argc, char **argv)
#endif
int
i
,
cdrom_index
;
int
snapshot
,
linux_boot
;
CPUState
*
env
;
const
char
*
initrd_filename
;
const
char
*
hd_filename
[
MAX_DISKS
],
*
fd_filename
[
MAX_FD
];
const
char
*
kernel_filename
,
*
kernel_cmdline
;
...
...
@@ -4511,6 +4536,13 @@ int main(int argc, char **argv)
optarg
);
usb_devices_index
++
;
break
;
case
QEMU_OPTION_smp
:
smp_cpus
=
atoi
(
optarg
);
if
(
smp_cpus
<
1
||
smp_cpus
>
8
)
{
fprintf
(
stderr
,
"Invalid number of CPUs
\n
"
);
exit
(
1
);
}
break
;
}
}
}
...
...
@@ -4659,15 +4691,8 @@ int main(int argc, char **argv)
}
}
/* init CPU state */
env
=
cpu_init
();
global_env
=
env
;
cpu_single_env
=
env
;
register_savevm
(
"timer"
,
0
,
1
,
timer_save
,
timer_load
,
env
);
register_savevm
(
"cpu"
,
0
,
3
,
cpu_save
,
cpu_load
,
env
);
register_savevm
(
"timer"
,
0
,
1
,
timer_save
,
timer_load
,
NULL
);
register_savevm
(
"ram"
,
0
,
1
,
ram_save
,
ram_load
,
NULL
);
qemu_register_reset
(
main_cpu_reset
,
global_env
);
init_ioports
();
cpu_calibrate_ticks
();
...
...
vl.h
浏览文件 @
6a00d601
...
...
@@ -142,6 +142,7 @@ extern const char *keyboard_layout;
extern
int
kqemu_allowed
;
extern
int
win2k_install_hack
;
extern
int
usb_enabled
;
extern
int
smp_cpus
;
/* XXX: make it dynamic */
#if defined (TARGET_PPC)
...
...
@@ -429,6 +430,9 @@ int register_savevm(const char *idstr,
void
qemu_get_timer
(
QEMUFile
*
f
,
QEMUTimer
*
ts
);
void
qemu_put_timer
(
QEMUFile
*
f
,
QEMUTimer
*
ts
);
void
cpu_save
(
QEMUFile
*
f
,
void
*
opaque
);
int
cpu_load
(
QEMUFile
*
f
,
void
*
opaque
,
int
version_id
);
/* block.c */
typedef
struct
BlockDriverState
BlockDriverState
;
typedef
struct
BlockDriver
BlockDriver
;
...
...
@@ -774,6 +778,9 @@ int pit_get_out(PITState *pit, int channel, int64_t current_time);
extern
QEMUMachine
pc_machine
;
extern
QEMUMachine
isapc_machine
;
void
ioport_set_a20
(
int
enable
);
int
ioport_get_a20
(
void
);
/* ppc.c */
extern
QEMUMachine
prep_machine
;
extern
QEMUMachine
core99_machine
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录