QOM CPUState refactorings
* Fix NULL pointer dereference in gdbstub * Introduce vaddr type * Introduce CPUClass::set_pc() * Introduce CPUClass::synchronize_from_tb() * Introduce CPUClass::get_phys_page_debug() * Introduce CPUClass::memory_rw_debug() * Move singlestep_enabled and gdb_regs fields out of CPU_COMMON * Adopt CPUState in more APIs * Propagate CPUState in gdbstub -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iQIcBAABAgAGBQJR7dNJAAoJEPou0S0+fgE/R8IQAKByM7NGK9JCbMuuZgLzbtib J1t6cpdn6ghD/qTNUoC6TuCLB0XHlFenfHtLSC9uqMXZPX1i6UZIo2yRA69X2IEu NjUU6LdoduEYL0jBkZeBSvx1SgMVwiabR6kvQorpEzmJWXQdRav8aNCQuGEgvIcb sv8kA6Jwh0+S4HJm3gGMs/wBSSeVpP3SUB14RiZESIFQpOovP+i1Qs8qTtclYf4j P3qxwoUCJy0S9ayQ6bGJKTbVkY4oCgZHQzDJ09rRT3KM0SMto/cfmlks2zynbeak 6RXa7iJ8UO4AyxcL37Va5QfVx+EKeu6TpMPxEEFqqgoxac9p4QPspvMmCv6XM4Ul TGldagWXHnyN9R5p/w6xMWoKizBE2AUPZh/N8CHI0zAvmaz0pfsiOotVEfs5lbi6 B5At9lgikagLV43Usi090xOIa3sVL5N+lqxm8PB6UlWbdpFPSBU6Vgx9UBbQniAd eB0SP5BUaqM5pkoCHXprrOyCLs3rkEflS1/o1jd+LxH1czQXruns1bEKal/PW22m a4TmDQd4X0IvgcziJzo5TuwR4cqQWc5REr2M+EnyMsb0oT5bdCoDZc9oSz+uOW3I Qs5hMjs2mG1192heO6HF5YwFzv5RT2POXLtjM+eW72zN4uMrOiIsXU+neQUyWb20 4+RywuU7mCFOX70UisL9 =AkgR -----END PGP SIGNATURE----- Merge remote-tracking branch 'afaerber/tags/qom-cpu-for-anthony' into staging QOM CPUState refactorings * Fix NULL pointer dereference in gdbstub * Introduce vaddr type * Introduce CPUClass::set_pc() * Introduce CPUClass::synchronize_from_tb() * Introduce CPUClass::get_phys_page_debug() * Introduce CPUClass::memory_rw_debug() * Move singlestep_enabled and gdb_regs fields out of CPU_COMMON * Adopt CPUState in more APIs * Propagate CPUState in gdbstub # gpg: Signature made Mon 22 Jul 2013 07:50:17 PM CDT using RSA key ID 3E7E013F # gpg: Can't check signature: public key not found # By Andreas Färber (21) and others # Via Andreas Färber * afaerber/tags/qom-cpu-for-anthony: (24 commits) linux-user: Use X86CPU property to retrieve CPUID family gdbstub: Change gdb_register_coprocessor() argument to CPUState cpu: Move gdb_regs field from CPU_COMMON to CPUState gdbstub: Change GDBState::{c,g}_cpu and find_cpu() to CPUState cpu: Introduce CPUClass::memory_rw_debug() for target_memory_rw_debug() exec: Change cpu_memory_rw_debug() argument to CPUState cpu: Turn cpu_get_phys_page_debug() into a CPUClass hook gdbstub: Change gdb_{read,write}_register() argument to CPUState gdbstub: Change gdb_handlesig() argument to CPUState gdbstub: Change syscall callback argument to CPUState kvm: Change kvm_{insert,remove}_breakpoint() argument to CPUState cpu: Change cpu_single_step() argument to CPUState gdbstub: Update gdb_handlesig() and gdb_signalled() Coding Style cpu: Move singlestep_enabled field from CPU_COMMON to CPUState target-alpha: Copy implver to DisasContext target-alpha: Copy singlestep_enabled to DisasContext cpu: Introduce CPUClass::synchronize_from_tb() for cpu_pc_from_tb() target-unicore32: Implement CPUClass::set_pc() target-moxie: Implement CPUClass::set_pc() target-m68k: Implement CPUClass::set_pc() ...
This commit is contained in:
commit
3988982c82
19
HACKING
19
HACKING
|
@ -40,8 +40,23 @@ speaking, the size of guest memory can always fit into ram_addr_t but
|
||||||
it would not be correct to store an actual guest physical address in a
|
it would not be correct to store an actual guest physical address in a
|
||||||
ram_addr_t.
|
ram_addr_t.
|
||||||
|
|
||||||
Use target_ulong (or abi_ulong) for CPU virtual addresses, however
|
For CPU virtual addresses there are several possible types.
|
||||||
devices should not need to use target_ulong.
|
vaddr is the best type to use to hold a CPU virtual address in
|
||||||
|
target-independent code. It is guaranteed to be large enough to hold a
|
||||||
|
virtual address for any target, and it does not change size from target
|
||||||
|
to target. It is always unsigned.
|
||||||
|
target_ulong is a type the size of a virtual address on the CPU; this means
|
||||||
|
it may be 32 or 64 bits depending on which target is being built. It should
|
||||||
|
therefore be used only in target-specific code, and in some
|
||||||
|
performance-critical built-per-target core code such as the TLB code.
|
||||||
|
There is also a signed version, target_long.
|
||||||
|
abi_ulong is for the *-user targets, and represents a type the size of
|
||||||
|
'void *' in that target's ABI. (This may not be the same as the size of a
|
||||||
|
full CPU virtual address in the case of target ABIs which use 32 bit pointers
|
||||||
|
on 64 bit CPUs, like sparc32plus.) Definitions of structures that must match
|
||||||
|
the target's ABI must use this type for anything that on the target is defined
|
||||||
|
to be an 'unsigned long' or a pointer type.
|
||||||
|
There is also a signed version, abi_long.
|
||||||
|
|
||||||
Of course, take all of the above with a grain of salt. If you're about
|
Of course, take all of the above with a grain of salt. If you're about
|
||||||
to use some system interface that requires a type like size_t, pid_t or
|
to use some system interface that requires a type like size_t, pid_t or
|
||||||
|
|
|
@ -643,7 +643,7 @@ void cpu_loop(CPUSPARCState *env)
|
||||||
{
|
{
|
||||||
int sig;
|
int sig;
|
||||||
|
|
||||||
sig = gdb_handlesig (env, TARGET_SIGTRAP);
|
sig = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||||
#if 0
|
#if 0
|
||||||
if (sig)
|
if (sig)
|
||||||
{
|
{
|
||||||
|
@ -738,6 +738,7 @@ int main(int argc, char **argv)
|
||||||
struct image_info info1, *info = &info1;
|
struct image_info info1, *info = &info1;
|
||||||
TaskState ts1, *ts = &ts1;
|
TaskState ts1, *ts = &ts1;
|
||||||
CPUArchState *env;
|
CPUArchState *env;
|
||||||
|
CPUState *cpu;
|
||||||
int optind;
|
int optind;
|
||||||
const char *r;
|
const char *r;
|
||||||
int gdbstub_port = 0;
|
int gdbstub_port = 0;
|
||||||
|
@ -912,10 +913,11 @@ int main(int argc, char **argv)
|
||||||
fprintf(stderr, "Unable to find CPU definition\n");
|
fprintf(stderr, "Unable to find CPU definition\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
cpu = ENV_GET_CPU(env);
|
||||||
#if defined(TARGET_SPARC) || defined(TARGET_PPC)
|
#if defined(TARGET_SPARC) || defined(TARGET_PPC)
|
||||||
cpu_reset(ENV_GET_CPU(env));
|
cpu_reset(cpu);
|
||||||
#endif
|
#endif
|
||||||
thread_cpu = ENV_GET_CPU(env);
|
thread_cpu = cpu;
|
||||||
|
|
||||||
if (getenv("QEMU_STRACE")) {
|
if (getenv("QEMU_STRACE")) {
|
||||||
do_strace = 1;
|
do_strace = 1;
|
||||||
|
@ -1134,7 +1136,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
if (gdbstub_port) {
|
if (gdbstub_port) {
|
||||||
gdbserver_start (gdbstub_port);
|
gdbserver_start (gdbstub_port);
|
||||||
gdb_handlesig(env, 0);
|
gdb_handlesig(cpu, 0);
|
||||||
}
|
}
|
||||||
cpu_loop(env);
|
cpu_loop(env);
|
||||||
/* never exits */
|
/* never exits */
|
||||||
|
|
10
cpu-exec.c
10
cpu-exec.c
|
@ -59,8 +59,14 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr)
|
||||||
* counter hit zero); we must restore the guest PC to the address
|
* counter hit zero); we must restore the guest PC to the address
|
||||||
* of the start of the TB.
|
* of the start of the TB.
|
||||||
*/
|
*/
|
||||||
|
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||||
TranslationBlock *tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
|
TranslationBlock *tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
|
||||||
cpu_pc_from_tb(env, tb);
|
if (cc->synchronize_from_tb) {
|
||||||
|
cc->synchronize_from_tb(cpu, tb);
|
||||||
|
} else {
|
||||||
|
assert(cc->set_pc);
|
||||||
|
cc->set_pc(cpu, tb->pc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ((next_tb & TB_EXIT_MASK) == TB_EXIT_REQUESTED) {
|
if ((next_tb & TB_EXIT_MASK) == TB_EXIT_REQUESTED) {
|
||||||
/* We were asked to stop executing TBs (probably a pending
|
/* We were asked to stop executing TBs (probably a pending
|
||||||
|
@ -291,7 +297,7 @@ int cpu_exec(CPUArchState *env)
|
||||||
for(;;) {
|
for(;;) {
|
||||||
interrupt_request = cpu->interrupt_request;
|
interrupt_request = cpu->interrupt_request;
|
||||||
if (unlikely(interrupt_request)) {
|
if (unlikely(interrupt_request)) {
|
||||||
if (unlikely(env->singlestep_enabled & SSTEP_NOIRQ)) {
|
if (unlikely(cpu->singlestep_enabled & SSTEP_NOIRQ)) {
|
||||||
/* Mask out external interrupts for this step. */
|
/* Mask out external interrupts for this step. */
|
||||||
interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK;
|
interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK;
|
||||||
}
|
}
|
||||||
|
|
6
cpus.c
6
cpus.c
|
@ -1186,7 +1186,7 @@ static void tcg_exec_all(void)
|
||||||
CPUArchState *env = cpu->env_ptr;
|
CPUArchState *env = cpu->env_ptr;
|
||||||
|
|
||||||
qemu_clock_enable(vm_clock,
|
qemu_clock_enable(vm_clock,
|
||||||
(env->singlestep_enabled & SSTEP_NOTIMER) == 0);
|
(cpu->singlestep_enabled & SSTEP_NOTIMER) == 0);
|
||||||
|
|
||||||
if (cpu_can_run(cpu)) {
|
if (cpu_can_run(cpu)) {
|
||||||
r = tcg_cpu_exec(env);
|
r = tcg_cpu_exec(env);
|
||||||
|
@ -1285,7 +1285,6 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename,
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
uint32_t l;
|
uint32_t l;
|
||||||
CPUArchState *env;
|
|
||||||
CPUState *cpu;
|
CPUState *cpu;
|
||||||
uint8_t buf[1024];
|
uint8_t buf[1024];
|
||||||
|
|
||||||
|
@ -1299,7 +1298,6 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename,
|
||||||
"a CPU number");
|
"a CPU number");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
env = cpu->env_ptr;
|
|
||||||
|
|
||||||
f = fopen(filename, "wb");
|
f = fopen(filename, "wb");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
|
@ -1311,7 +1309,7 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename,
|
||||||
l = sizeof(buf);
|
l = sizeof(buf);
|
||||||
if (l > size)
|
if (l > size)
|
||||||
l = size;
|
l = size;
|
||||||
cpu_memory_rw_debug(env, addr, buf, l, 0);
|
cpu_memory_rw_debug(cpu, addr, buf, l, 0);
|
||||||
if (fwrite(buf, 1, l, f) != l) {
|
if (fwrite(buf, 1, l, f) != l) {
|
||||||
error_set(errp, QERR_IO_ERROR);
|
error_set(errp, QERR_IO_ERROR);
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
4
disas.c
4
disas.c
|
@ -39,7 +39,7 @@ target_read_memory (bfd_vma memaddr,
|
||||||
{
|
{
|
||||||
CPUDebug *s = container_of(info, CPUDebug, info);
|
CPUDebug *s = container_of(info, CPUDebug, info);
|
||||||
|
|
||||||
cpu_memory_rw_debug(s->env, memaddr, myaddr, length, 0);
|
cpu_memory_rw_debug(ENV_GET_CPU(s->env), memaddr, myaddr, length, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,7 +392,7 @@ monitor_read_memory (bfd_vma memaddr, bfd_byte *myaddr, int length,
|
||||||
if (monitor_disas_is_physical) {
|
if (monitor_disas_is_physical) {
|
||||||
cpu_physical_memory_read(memaddr, myaddr, length);
|
cpu_physical_memory_read(memaddr, myaddr, length);
|
||||||
} else {
|
} else {
|
||||||
cpu_memory_rw_debug(s->env, memaddr,myaddr, length, 0);
|
cpu_memory_rw_debug(ENV_GET_CPU(s->env), memaddr, myaddr, length, 0);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
36
exec.c
36
exec.c
|
@ -415,14 +415,14 @@ void cpu_exec_init(CPUArchState *env)
|
||||||
|
|
||||||
#if defined(TARGET_HAS_ICE)
|
#if defined(TARGET_HAS_ICE)
|
||||||
#if defined(CONFIG_USER_ONLY)
|
#if defined(CONFIG_USER_ONLY)
|
||||||
static void breakpoint_invalidate(CPUArchState *env, target_ulong pc)
|
static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
|
||||||
{
|
{
|
||||||
tb_invalidate_phys_page_range(pc, pc + 1, 0);
|
tb_invalidate_phys_page_range(pc, pc + 1, 0);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static void breakpoint_invalidate(CPUArchState *env, target_ulong pc)
|
static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
|
||||||
{
|
{
|
||||||
tb_invalidate_phys_addr(cpu_get_phys_page_debug(env, pc) |
|
tb_invalidate_phys_addr(cpu_get_phys_page_debug(cpu, pc) |
|
||||||
(pc & ~TARGET_PAGE_MASK));
|
(pc & ~TARGET_PAGE_MASK));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -525,15 +525,17 @@ int cpu_breakpoint_insert(CPUArchState *env, target_ulong pc, int flags,
|
||||||
bp->flags = flags;
|
bp->flags = flags;
|
||||||
|
|
||||||
/* keep all GDB-injected breakpoints in front */
|
/* keep all GDB-injected breakpoints in front */
|
||||||
if (flags & BP_GDB)
|
if (flags & BP_GDB) {
|
||||||
QTAILQ_INSERT_HEAD(&env->breakpoints, bp, entry);
|
QTAILQ_INSERT_HEAD(&env->breakpoints, bp, entry);
|
||||||
else
|
} else {
|
||||||
QTAILQ_INSERT_TAIL(&env->breakpoints, bp, entry);
|
QTAILQ_INSERT_TAIL(&env->breakpoints, bp, entry);
|
||||||
|
}
|
||||||
|
|
||||||
breakpoint_invalidate(env, pc);
|
breakpoint_invalidate(ENV_GET_CPU(env), pc);
|
||||||
|
|
||||||
if (breakpoint)
|
if (breakpoint) {
|
||||||
*breakpoint = bp;
|
*breakpoint = bp;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
#else
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
|
@ -564,7 +566,7 @@ void cpu_breakpoint_remove_by_ref(CPUArchState *env, CPUBreakpoint *breakpoint)
|
||||||
#if defined(TARGET_HAS_ICE)
|
#if defined(TARGET_HAS_ICE)
|
||||||
QTAILQ_REMOVE(&env->breakpoints, breakpoint, entry);
|
QTAILQ_REMOVE(&env->breakpoints, breakpoint, entry);
|
||||||
|
|
||||||
breakpoint_invalidate(env, breakpoint->pc);
|
breakpoint_invalidate(ENV_GET_CPU(env), breakpoint->pc);
|
||||||
|
|
||||||
g_free(breakpoint);
|
g_free(breakpoint);
|
||||||
#endif
|
#endif
|
||||||
|
@ -585,14 +587,16 @@ void cpu_breakpoint_remove_all(CPUArchState *env, int mask)
|
||||||
|
|
||||||
/* enable or disable single step mode. EXCP_DEBUG is returned by the
|
/* enable or disable single step mode. EXCP_DEBUG is returned by the
|
||||||
CPU loop after each instruction */
|
CPU loop after each instruction */
|
||||||
void cpu_single_step(CPUArchState *env, int enabled)
|
void cpu_single_step(CPUState *cpu, int enabled)
|
||||||
{
|
{
|
||||||
#if defined(TARGET_HAS_ICE)
|
#if defined(TARGET_HAS_ICE)
|
||||||
if (env->singlestep_enabled != enabled) {
|
CPUArchState *env = cpu->env_ptr;
|
||||||
env->singlestep_enabled = enabled;
|
|
||||||
if (kvm_enabled())
|
if (cpu->singlestep_enabled != enabled) {
|
||||||
|
cpu->singlestep_enabled = enabled;
|
||||||
|
if (kvm_enabled()) {
|
||||||
kvm_update_guest_debug(env, 0);
|
kvm_update_guest_debug(env, 0);
|
||||||
else {
|
} else {
|
||||||
/* must flush all the translated code to avoid inconsistencies */
|
/* must flush all the translated code to avoid inconsistencies */
|
||||||
/* XXX: only flush what is necessary */
|
/* XXX: only flush what is necessary */
|
||||||
tb_flush(env);
|
tb_flush(env);
|
||||||
|
@ -1831,7 +1835,7 @@ MemoryRegion *get_system_io(void)
|
||||||
|
|
||||||
/* physical memory access (slow version, mainly for debug) */
|
/* physical memory access (slow version, mainly for debug) */
|
||||||
#if defined(CONFIG_USER_ONLY)
|
#if defined(CONFIG_USER_ONLY)
|
||||||
int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,
|
int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
|
||||||
uint8_t *buf, int len, int is_write)
|
uint8_t *buf, int len, int is_write)
|
||||||
{
|
{
|
||||||
int l, flags;
|
int l, flags;
|
||||||
|
@ -2602,7 +2606,7 @@ void stq_be_phys(hwaddr addr, uint64_t val)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* virtual memory access for debug (includes writing to ROM) */
|
/* virtual memory access for debug (includes writing to ROM) */
|
||||||
int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,
|
int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
|
||||||
uint8_t *buf, int len, int is_write)
|
uint8_t *buf, int len, int is_write)
|
||||||
{
|
{
|
||||||
int l;
|
int l;
|
||||||
|
@ -2611,7 +2615,7 @@ int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,
|
||||||
|
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
page = addr & TARGET_PAGE_MASK;
|
page = addr & TARGET_PAGE_MASK;
|
||||||
phys_addr = cpu_get_phys_page_debug(env, page);
|
phys_addr = cpu_get_phys_page_debug(cpu, page);
|
||||||
/* if no physical page mapped, return an error */
|
/* if no physical page mapped, return an error */
|
||||||
if (phys_addr == -1)
|
if (phys_addr == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
266
gdbstub.c
266
gdbstub.c
|
@ -42,15 +42,16 @@
|
||||||
#include "sysemu/kvm.h"
|
#include "sysemu/kvm.h"
|
||||||
#include "qemu/bitops.h"
|
#include "qemu/bitops.h"
|
||||||
|
|
||||||
#ifndef TARGET_CPU_MEMORY_RW_DEBUG
|
static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr,
|
||||||
static inline int target_memory_rw_debug(CPUArchState *env, target_ulong addr,
|
uint8_t *buf, int len, bool is_write)
|
||||||
uint8_t *buf, int len, int is_write)
|
|
||||||
{
|
{
|
||||||
return cpu_memory_rw_debug(env, addr, buf, len, is_write);
|
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||||
|
|
||||||
|
if (cc->memory_rw_debug) {
|
||||||
|
return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
|
||||||
|
}
|
||||||
|
return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
/* target_memory_rw_debug() defined in cpu.h */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
GDB_SIGNAL_0 = 0,
|
GDB_SIGNAL_0 = 0,
|
||||||
|
@ -287,9 +288,9 @@ enum RSState {
|
||||||
RS_CHKSUM2,
|
RS_CHKSUM2,
|
||||||
};
|
};
|
||||||
typedef struct GDBState {
|
typedef struct GDBState {
|
||||||
CPUArchState *c_cpu; /* current CPU for step/continue ops */
|
CPUState *c_cpu; /* current CPU for step/continue ops */
|
||||||
CPUArchState *g_cpu; /* current CPU for other ops */
|
CPUState *g_cpu; /* current CPU for other ops */
|
||||||
CPUArchState *query_cpu; /* for q{f|s}ThreadInfo */
|
CPUState *query_cpu; /* for q{f|s}ThreadInfo */
|
||||||
enum RSState state; /* parsing state */
|
enum RSState state; /* parsing state */
|
||||||
char line_buf[MAX_PACKET_LENGTH];
|
char line_buf[MAX_PACKET_LENGTH];
|
||||||
int line_buf_index;
|
int line_buf_index;
|
||||||
|
@ -1839,7 +1840,7 @@ static const char *get_feature_xml(const char *p, const char **newp)
|
||||||
/* Generate the XML description for this CPU. */
|
/* Generate the XML description for this CPU. */
|
||||||
if (!target_xml[0]) {
|
if (!target_xml[0]) {
|
||||||
GDBRegisterState *r;
|
GDBRegisterState *r;
|
||||||
CPUArchState *env = first_cpu->env_ptr;
|
CPUState *cpu = first_cpu;
|
||||||
|
|
||||||
snprintf(target_xml, sizeof(target_xml),
|
snprintf(target_xml, sizeof(target_xml),
|
||||||
"<?xml version=\"1.0\"?>"
|
"<?xml version=\"1.0\"?>"
|
||||||
|
@ -1848,7 +1849,7 @@ static const char *get_feature_xml(const char *p, const char **newp)
|
||||||
"<xi:include href=\"%s\"/>",
|
"<xi:include href=\"%s\"/>",
|
||||||
GDB_CORE_XML);
|
GDB_CORE_XML);
|
||||||
|
|
||||||
for (r = env->gdb_regs; r; r = r->next) {
|
for (r = cpu->gdb_regs; r; r = r->next) {
|
||||||
pstrcat(target_xml, sizeof(target_xml), "<xi:include href=\"");
|
pstrcat(target_xml, sizeof(target_xml), "<xi:include href=\"");
|
||||||
pstrcat(target_xml, sizeof(target_xml), r->xml);
|
pstrcat(target_xml, sizeof(target_xml), r->xml);
|
||||||
pstrcat(target_xml, sizeof(target_xml), "\"/>");
|
pstrcat(target_xml, sizeof(target_xml), "\"/>");
|
||||||
|
@ -1866,14 +1867,15 @@ static const char *get_feature_xml(const char *p, const char **newp)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int gdb_read_register(CPUArchState *env, uint8_t *mem_buf, int reg)
|
static int gdb_read_register(CPUState *cpu, uint8_t *mem_buf, int reg)
|
||||||
{
|
{
|
||||||
|
CPUArchState *env = cpu->env_ptr;
|
||||||
GDBRegisterState *r;
|
GDBRegisterState *r;
|
||||||
|
|
||||||
if (reg < NUM_CORE_REGS)
|
if (reg < NUM_CORE_REGS)
|
||||||
return cpu_gdb_read_register(env, mem_buf, reg);
|
return cpu_gdb_read_register(env, mem_buf, reg);
|
||||||
|
|
||||||
for (r = env->gdb_regs; r; r = r->next) {
|
for (r = cpu->gdb_regs; r; r = r->next) {
|
||||||
if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
|
if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
|
||||||
return r->get_reg(env, mem_buf, reg - r->base_reg);
|
return r->get_reg(env, mem_buf, reg - r->base_reg);
|
||||||
}
|
}
|
||||||
|
@ -1881,14 +1883,15 @@ static int gdb_read_register(CPUArchState *env, uint8_t *mem_buf, int reg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gdb_write_register(CPUArchState *env, uint8_t *mem_buf, int reg)
|
static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
|
||||||
{
|
{
|
||||||
|
CPUArchState *env = cpu->env_ptr;
|
||||||
GDBRegisterState *r;
|
GDBRegisterState *r;
|
||||||
|
|
||||||
if (reg < NUM_CORE_REGS)
|
if (reg < NUM_CORE_REGS)
|
||||||
return cpu_gdb_write_register(env, mem_buf, reg);
|
return cpu_gdb_write_register(env, mem_buf, reg);
|
||||||
|
|
||||||
for (r = env->gdb_regs; r; r = r->next) {
|
for (r = cpu->gdb_regs; r; r = r->next) {
|
||||||
if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
|
if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
|
||||||
return r->set_reg(env, mem_buf, reg - r->base_reg);
|
return r->set_reg(env, mem_buf, reg - r->base_reg);
|
||||||
}
|
}
|
||||||
|
@ -1903,15 +1906,15 @@ static int gdb_write_register(CPUArchState *env, uint8_t *mem_buf, int reg)
|
||||||
gdb reading a CPU register, and set_reg is gdb modifying a CPU register.
|
gdb reading a CPU register, and set_reg is gdb modifying a CPU register.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void gdb_register_coprocessor(CPUArchState * env,
|
void gdb_register_coprocessor(CPUState *cpu,
|
||||||
gdb_reg_cb get_reg, gdb_reg_cb set_reg,
|
gdb_reg_cb get_reg, gdb_reg_cb set_reg,
|
||||||
int num_regs, const char *xml, int g_pos)
|
int num_regs, const char *xml, int g_pos)
|
||||||
{
|
{
|
||||||
GDBRegisterState *s;
|
GDBRegisterState *s;
|
||||||
GDBRegisterState **p;
|
GDBRegisterState **p;
|
||||||
static int last_reg = NUM_CORE_REGS;
|
static int last_reg = NUM_CORE_REGS;
|
||||||
|
|
||||||
p = &env->gdb_regs;
|
p = &cpu->gdb_regs;
|
||||||
while (*p) {
|
while (*p) {
|
||||||
/* Check for duplicates. */
|
/* Check for duplicates. */
|
||||||
if (strcmp((*p)->xml, xml) == 0)
|
if (strcmp((*p)->xml, xml) == 0)
|
||||||
|
@ -1954,8 +1957,9 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
|
||||||
CPUArchState *env;
|
CPUArchState *env;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (kvm_enabled())
|
if (kvm_enabled()) {
|
||||||
return kvm_insert_breakpoint(gdbserver_state->c_cpu, addr, len, type);
|
return kvm_insert_breakpoint(gdbserver_state->c_cpu, addr, len, type);
|
||||||
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case GDB_BREAKPOINT_SW:
|
case GDB_BREAKPOINT_SW:
|
||||||
|
@ -1991,8 +1995,9 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
|
||||||
CPUArchState *env;
|
CPUArchState *env;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
if (kvm_enabled())
|
if (kvm_enabled()) {
|
||||||
return kvm_remove_breakpoint(gdbserver_state->c_cpu, addr, len, type);
|
return kvm_remove_breakpoint(gdbserver_state->c_cpu, addr, len, type);
|
||||||
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case GDB_BREAKPOINT_SW:
|
case GDB_BREAKPOINT_SW:
|
||||||
|
@ -2027,7 +2032,7 @@ static void gdb_breakpoint_remove_all(void)
|
||||||
CPUArchState *env;
|
CPUArchState *env;
|
||||||
|
|
||||||
if (kvm_enabled()) {
|
if (kvm_enabled()) {
|
||||||
kvm_remove_all_breakpoints(ENV_GET_CPU(gdbserver_state->c_cpu));
|
kvm_remove_all_breakpoints(gdbserver_state->c_cpu);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2042,49 +2047,22 @@ static void gdb_breakpoint_remove_all(void)
|
||||||
|
|
||||||
static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
|
static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
|
||||||
{
|
{
|
||||||
cpu_synchronize_state(ENV_GET_CPU(s->c_cpu));
|
CPUState *cpu = s->c_cpu;
|
||||||
#if defined(TARGET_I386)
|
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||||
s->c_cpu->eip = pc;
|
|
||||||
#elif defined (TARGET_PPC)
|
cpu_synchronize_state(cpu);
|
||||||
s->c_cpu->nip = pc;
|
if (cc->set_pc) {
|
||||||
#elif defined (TARGET_SPARC)
|
cc->set_pc(cpu, pc);
|
||||||
s->c_cpu->pc = pc;
|
|
||||||
s->c_cpu->npc = pc + 4;
|
|
||||||
#elif defined (TARGET_ARM)
|
|
||||||
s->c_cpu->regs[15] = pc;
|
|
||||||
#elif defined (TARGET_SH4)
|
|
||||||
s->c_cpu->pc = pc;
|
|
||||||
#elif defined (TARGET_MIPS)
|
|
||||||
s->c_cpu->active_tc.PC = pc & ~(target_ulong)1;
|
|
||||||
if (pc & 1) {
|
|
||||||
s->c_cpu->hflags |= MIPS_HFLAG_M16;
|
|
||||||
} else {
|
|
||||||
s->c_cpu->hflags &= ~(MIPS_HFLAG_M16);
|
|
||||||
}
|
}
|
||||||
#elif defined (TARGET_MICROBLAZE)
|
|
||||||
s->c_cpu->sregs[SR_PC] = pc;
|
|
||||||
#elif defined(TARGET_OPENRISC)
|
|
||||||
s->c_cpu->pc = pc;
|
|
||||||
#elif defined (TARGET_CRIS)
|
|
||||||
s->c_cpu->pc = pc;
|
|
||||||
#elif defined (TARGET_ALPHA)
|
|
||||||
s->c_cpu->pc = pc;
|
|
||||||
#elif defined (TARGET_S390X)
|
|
||||||
s->c_cpu->psw.addr = pc;
|
|
||||||
#elif defined (TARGET_LM32)
|
|
||||||
s->c_cpu->pc = pc;
|
|
||||||
#elif defined(TARGET_XTENSA)
|
|
||||||
s->c_cpu->pc = pc;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static CPUArchState *find_cpu(uint32_t thread_id)
|
static CPUState *find_cpu(uint32_t thread_id)
|
||||||
{
|
{
|
||||||
CPUState *cpu;
|
CPUState *cpu;
|
||||||
|
|
||||||
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
|
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
|
||||||
if (cpu_index(cpu) == thread_id) {
|
if (cpu_index(cpu) == thread_id) {
|
||||||
return cpu->env_ptr;
|
return cpu;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2093,7 +2071,10 @@ static CPUArchState *find_cpu(uint32_t thread_id)
|
||||||
|
|
||||||
static int gdb_handle_packet(GDBState *s, const char *line_buf)
|
static int gdb_handle_packet(GDBState *s, const char *line_buf)
|
||||||
{
|
{
|
||||||
|
#ifdef TARGET_XTENSA
|
||||||
CPUArchState *env;
|
CPUArchState *env;
|
||||||
|
#endif
|
||||||
|
CPUState *cpu;
|
||||||
const char *p;
|
const char *p;
|
||||||
uint32_t thread;
|
uint32_t thread;
|
||||||
int ch, reg_size, type, res;
|
int ch, reg_size, type, res;
|
||||||
|
@ -2111,7 +2092,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
|
||||||
case '?':
|
case '?':
|
||||||
/* TODO: Make this return the correct value for user-mode. */
|
/* TODO: Make this return the correct value for user-mode. */
|
||||||
snprintf(buf, sizeof(buf), "T%02xthread:%02x;", GDB_SIGNAL_TRAP,
|
snprintf(buf, sizeof(buf), "T%02xthread:%02x;", GDB_SIGNAL_TRAP,
|
||||||
cpu_index(ENV_GET_CPU(s->c_cpu)));
|
cpu_index(s->c_cpu));
|
||||||
put_packet(s, buf);
|
put_packet(s, buf);
|
||||||
/* Remove all the breakpoints when this query is issued,
|
/* Remove all the breakpoints when this query is issued,
|
||||||
* because gdb is doing and initial connect and the state
|
* because gdb is doing and initial connect and the state
|
||||||
|
@ -2173,12 +2154,12 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
|
||||||
}
|
}
|
||||||
if (res) {
|
if (res) {
|
||||||
if (res_thread != -1 && res_thread != 0) {
|
if (res_thread != -1 && res_thread != 0) {
|
||||||
env = find_cpu(res_thread);
|
cpu = find_cpu(res_thread);
|
||||||
if (env == NULL) {
|
if (cpu == NULL) {
|
||||||
put_packet(s, "E22");
|
put_packet(s, "E22");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
s->c_cpu = env;
|
s->c_cpu = cpu;
|
||||||
}
|
}
|
||||||
if (res == 's') {
|
if (res == 's') {
|
||||||
cpu_single_step(s->c_cpu, sstep_flags);
|
cpu_single_step(s->c_cpu, sstep_flags);
|
||||||
|
@ -2239,8 +2220,10 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'g':
|
case 'g':
|
||||||
cpu_synchronize_state(ENV_GET_CPU(s->g_cpu));
|
cpu_synchronize_state(s->g_cpu);
|
||||||
env = s->g_cpu;
|
#ifdef TARGET_XTENSA
|
||||||
|
env = s->g_cpu->env_ptr;
|
||||||
|
#endif
|
||||||
len = 0;
|
len = 0;
|
||||||
for (addr = 0; addr < num_g_regs; addr++) {
|
for (addr = 0; addr < num_g_regs; addr++) {
|
||||||
reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr);
|
reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr);
|
||||||
|
@ -2250,8 +2233,10 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
|
||||||
put_packet(s, buf);
|
put_packet(s, buf);
|
||||||
break;
|
break;
|
||||||
case 'G':
|
case 'G':
|
||||||
cpu_synchronize_state(ENV_GET_CPU(s->g_cpu));
|
cpu_synchronize_state(s->g_cpu);
|
||||||
env = s->g_cpu;
|
#ifdef TARGET_XTENSA
|
||||||
|
env = s->g_cpu->env_ptr;
|
||||||
|
#endif
|
||||||
registers = mem_buf;
|
registers = mem_buf;
|
||||||
len = strlen(p) / 2;
|
len = strlen(p) / 2;
|
||||||
hextomem((uint8_t *)registers, p, len);
|
hextomem((uint8_t *)registers, p, len);
|
||||||
|
@ -2267,7 +2252,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
|
||||||
if (*p == ',')
|
if (*p == ',')
|
||||||
p++;
|
p++;
|
||||||
len = strtoull(p, NULL, 16);
|
len = strtoull(p, NULL, 16);
|
||||||
if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 0) != 0) {
|
if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, false) != 0) {
|
||||||
put_packet (s, "E14");
|
put_packet (s, "E14");
|
||||||
} else {
|
} else {
|
||||||
memtohex(buf, mem_buf, len);
|
memtohex(buf, mem_buf, len);
|
||||||
|
@ -2282,7 +2267,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
|
||||||
if (*p == ':')
|
if (*p == ':')
|
||||||
p++;
|
p++;
|
||||||
hextomem(mem_buf, p, len);
|
hextomem(mem_buf, p, len);
|
||||||
if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 1) != 0) {
|
if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len,
|
||||||
|
true) != 0) {
|
||||||
put_packet(s, "E14");
|
put_packet(s, "E14");
|
||||||
} else {
|
} else {
|
||||||
put_packet(s, "OK");
|
put_packet(s, "OK");
|
||||||
|
@ -2341,18 +2327,18 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
|
||||||
put_packet(s, "OK");
|
put_packet(s, "OK");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
env = find_cpu(thread);
|
cpu = find_cpu(thread);
|
||||||
if (env == NULL) {
|
if (cpu == NULL) {
|
||||||
put_packet(s, "E22");
|
put_packet(s, "E22");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'c':
|
case 'c':
|
||||||
s->c_cpu = env;
|
s->c_cpu = cpu;
|
||||||
put_packet(s, "OK");
|
put_packet(s, "OK");
|
||||||
break;
|
break;
|
||||||
case 'g':
|
case 'g':
|
||||||
s->g_cpu = env;
|
s->g_cpu = cpu;
|
||||||
put_packet(s, "OK");
|
put_packet(s, "OK");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -2362,9 +2348,9 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
|
||||||
break;
|
break;
|
||||||
case 'T':
|
case 'T':
|
||||||
thread = strtoull(p, (char **)&p, 16);
|
thread = strtoull(p, (char **)&p, 16);
|
||||||
env = find_cpu(thread);
|
cpu = find_cpu(thread);
|
||||||
|
|
||||||
if (env != NULL) {
|
if (cpu != NULL) {
|
||||||
put_packet(s, "OK");
|
put_packet(s, "OK");
|
||||||
} else {
|
} else {
|
||||||
put_packet(s, "E22");
|
put_packet(s, "E22");
|
||||||
|
@ -2401,23 +2387,21 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
|
||||||
put_packet(s, "QC1");
|
put_packet(s, "QC1");
|
||||||
break;
|
break;
|
||||||
} else if (strcmp(p,"fThreadInfo") == 0) {
|
} else if (strcmp(p,"fThreadInfo") == 0) {
|
||||||
s->query_cpu = first_cpu->env_ptr;
|
s->query_cpu = first_cpu;
|
||||||
goto report_cpuinfo;
|
goto report_cpuinfo;
|
||||||
} else if (strcmp(p,"sThreadInfo") == 0) {
|
} else if (strcmp(p,"sThreadInfo") == 0) {
|
||||||
report_cpuinfo:
|
report_cpuinfo:
|
||||||
if (s->query_cpu) {
|
if (s->query_cpu) {
|
||||||
snprintf(buf, sizeof(buf), "m%x",
|
snprintf(buf, sizeof(buf), "m%x", cpu_index(s->query_cpu));
|
||||||
cpu_index(ENV_GET_CPU(s->query_cpu)));
|
|
||||||
put_packet(s, buf);
|
put_packet(s, buf);
|
||||||
s->query_cpu = ENV_GET_CPU(s->query_cpu)->next_cpu->env_ptr;
|
s->query_cpu = s->query_cpu->next_cpu;
|
||||||
} else
|
} else
|
||||||
put_packet(s, "l");
|
put_packet(s, "l");
|
||||||
break;
|
break;
|
||||||
} else if (strncmp(p,"ThreadExtraInfo,", 16) == 0) {
|
} else if (strncmp(p,"ThreadExtraInfo,", 16) == 0) {
|
||||||
thread = strtoull(p+16, (char **)&p, 16);
|
thread = strtoull(p+16, (char **)&p, 16);
|
||||||
env = find_cpu(thread);
|
cpu = find_cpu(thread);
|
||||||
if (env != NULL) {
|
if (cpu != NULL) {
|
||||||
CPUState *cpu = ENV_GET_CPU(env);
|
|
||||||
cpu_synchronize_state(cpu);
|
cpu_synchronize_state(cpu);
|
||||||
len = snprintf((char *)mem_buf, sizeof(mem_buf),
|
len = snprintf((char *)mem_buf, sizeof(mem_buf),
|
||||||
"CPU#%d [%s]", cpu->cpu_index,
|
"CPU#%d [%s]", cpu->cpu_index,
|
||||||
|
@ -2429,7 +2413,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_USER_ONLY
|
#ifdef CONFIG_USER_ONLY
|
||||||
else if (strncmp(p, "Offsets", 7) == 0) {
|
else if (strncmp(p, "Offsets", 7) == 0) {
|
||||||
TaskState *ts = s->c_cpu->opaque;
|
CPUArchState *env = s->c_cpu->env_ptr;
|
||||||
|
TaskState *ts = env->opaque;
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf),
|
snprintf(buf, sizeof(buf),
|
||||||
"Text=" TARGET_ABI_FMT_lx ";Data=" TARGET_ABI_FMT_lx
|
"Text=" TARGET_ABI_FMT_lx ";Data=" TARGET_ABI_FMT_lx
|
||||||
|
@ -2519,18 +2504,16 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
|
||||||
|
|
||||||
void gdb_set_stop_cpu(CPUState *cpu)
|
void gdb_set_stop_cpu(CPUState *cpu)
|
||||||
{
|
{
|
||||||
CPUArchState *env = cpu->env_ptr;
|
gdbserver_state->c_cpu = cpu;
|
||||||
|
gdbserver_state->g_cpu = cpu;
|
||||||
gdbserver_state->c_cpu = env;
|
|
||||||
gdbserver_state->g_cpu = env;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
static void gdb_vm_state_change(void *opaque, int running, RunState state)
|
static void gdb_vm_state_change(void *opaque, int running, RunState state)
|
||||||
{
|
{
|
||||||
GDBState *s = gdbserver_state;
|
GDBState *s = gdbserver_state;
|
||||||
CPUArchState *env = s->c_cpu;
|
CPUArchState *env = s->c_cpu->env_ptr;
|
||||||
CPUState *cpu = ENV_GET_CPU(env);
|
CPUState *cpu = s->c_cpu;
|
||||||
char buf[256];
|
char buf[256];
|
||||||
const char *type;
|
const char *type;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -2598,7 +2581,7 @@ send_packet:
|
||||||
put_packet(s, buf);
|
put_packet(s, buf);
|
||||||
|
|
||||||
/* disable single step if it was enabled */
|
/* disable single step if it was enabled */
|
||||||
cpu_single_step(env, 0);
|
cpu_single_step(cpu, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -2668,7 +2651,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
|
||||||
is still in the running state, which can cause packets to be dropped
|
is still in the running state, which can cause packets to be dropped
|
||||||
and state transition 'T' packets to be sent while the syscall is still
|
and state transition 'T' packets to be sent while the syscall is still
|
||||||
being processed. */
|
being processed. */
|
||||||
cpu_exit(ENV_GET_CPU(s->c_cpu));
|
cpu_exit(s->c_cpu);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2789,66 +2772,67 @@ gdb_queuesig (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
gdb_handlesig (CPUArchState *env, int sig)
|
gdb_handlesig(CPUState *cpu, int sig)
|
||||||
{
|
{
|
||||||
GDBState *s;
|
CPUArchState *env = cpu->env_ptr;
|
||||||
char buf[256];
|
GDBState *s;
|
||||||
int n;
|
char buf[256];
|
||||||
|
int n;
|
||||||
|
|
||||||
s = gdbserver_state;
|
s = gdbserver_state;
|
||||||
if (gdbserver_fd < 0 || s->fd < 0)
|
if (gdbserver_fd < 0 || s->fd < 0) {
|
||||||
return sig;
|
return sig;
|
||||||
|
|
||||||
/* disable single step if it was enabled */
|
|
||||||
cpu_single_step(env, 0);
|
|
||||||
tb_flush(env);
|
|
||||||
|
|
||||||
if (sig != 0)
|
|
||||||
{
|
|
||||||
snprintf(buf, sizeof(buf), "S%02x", target_signal_to_gdb (sig));
|
|
||||||
put_packet(s, buf);
|
|
||||||
}
|
}
|
||||||
/* put_packet() might have detected that the peer terminated the
|
|
||||||
connection. */
|
|
||||||
if (s->fd < 0)
|
|
||||||
return sig;
|
|
||||||
|
|
||||||
sig = 0;
|
/* disable single step if it was enabled */
|
||||||
s->state = RS_IDLE;
|
cpu_single_step(cpu, 0);
|
||||||
s->running_state = 0;
|
tb_flush(env);
|
||||||
while (s->running_state == 0) {
|
|
||||||
n = read (s->fd, buf, 256);
|
|
||||||
if (n > 0)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < n; i++)
|
if (sig != 0) {
|
||||||
gdb_read_byte (s, buf[i]);
|
snprintf(buf, sizeof(buf), "S%02x", target_signal_to_gdb(sig));
|
||||||
|
put_packet(s, buf);
|
||||||
|
}
|
||||||
|
/* put_packet() might have detected that the peer terminated the
|
||||||
|
connection. */
|
||||||
|
if (s->fd < 0) {
|
||||||
|
return sig;
|
||||||
|
}
|
||||||
|
|
||||||
|
sig = 0;
|
||||||
|
s->state = RS_IDLE;
|
||||||
|
s->running_state = 0;
|
||||||
|
while (s->running_state == 0) {
|
||||||
|
n = read(s->fd, buf, 256);
|
||||||
|
if (n > 0) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
gdb_read_byte(s, buf[i]);
|
||||||
|
}
|
||||||
|
} else if (n == 0 || errno != EAGAIN) {
|
||||||
|
/* XXX: Connection closed. Should probably wait for another
|
||||||
|
connection before continuing. */
|
||||||
|
return sig;
|
||||||
}
|
}
|
||||||
else if (n == 0 || errno != EAGAIN)
|
}
|
||||||
{
|
sig = s->signal;
|
||||||
/* XXX: Connection closed. Should probably wait for another
|
s->signal = 0;
|
||||||
connection before continuing. */
|
return sig;
|
||||||
return sig;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sig = s->signal;
|
|
||||||
s->signal = 0;
|
|
||||||
return sig;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tell the remote gdb that the process has exited due to SIG. */
|
/* Tell the remote gdb that the process has exited due to SIG. */
|
||||||
void gdb_signalled(CPUArchState *env, int sig)
|
void gdb_signalled(CPUArchState *env, int sig)
|
||||||
{
|
{
|
||||||
GDBState *s;
|
GDBState *s;
|
||||||
char buf[4];
|
char buf[4];
|
||||||
|
|
||||||
s = gdbserver_state;
|
s = gdbserver_state;
|
||||||
if (gdbserver_fd < 0 || s->fd < 0)
|
if (gdbserver_fd < 0 || s->fd < 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb (sig));
|
snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb(sig));
|
||||||
put_packet(s, buf);
|
put_packet(s, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gdb_accept(void)
|
static void gdb_accept(void)
|
||||||
|
@ -2876,8 +2860,8 @@ static void gdb_accept(void)
|
||||||
socket_set_nodelay(fd);
|
socket_set_nodelay(fd);
|
||||||
|
|
||||||
s = g_malloc0(sizeof(GDBState));
|
s = g_malloc0(sizeof(GDBState));
|
||||||
s->c_cpu = first_cpu->env_ptr;
|
s->c_cpu = first_cpu;
|
||||||
s->g_cpu = first_cpu->env_ptr;
|
s->g_cpu = first_cpu;
|
||||||
s->fd = fd;
|
s->fd = fd;
|
||||||
gdb_has_xml = 0;
|
gdb_has_xml = 0;
|
||||||
|
|
||||||
|
@ -3061,8 +3045,8 @@ int gdbserver_start(const char *device)
|
||||||
mon_chr = s->mon_chr;
|
mon_chr = s->mon_chr;
|
||||||
memset(s, 0, sizeof(GDBState));
|
memset(s, 0, sizeof(GDBState));
|
||||||
}
|
}
|
||||||
s->c_cpu = first_cpu->env_ptr;
|
s->c_cpu = first_cpu;
|
||||||
s->g_cpu = first_cpu->env_ptr;
|
s->g_cpu = first_cpu;
|
||||||
s->chr = chr;
|
s->chr = chr;
|
||||||
s->state = chr ? RS_IDLE : RS_INACTIVE;
|
s->state = chr ? RS_IDLE : RS_INACTIVE;
|
||||||
s->mon_chr = mon_chr;
|
s->mon_chr = mon_chr;
|
||||||
|
|
|
@ -146,6 +146,7 @@ static void update_guest_rom_state(VAPICROMState *s)
|
||||||
|
|
||||||
static int find_real_tpr_addr(VAPICROMState *s, CPUX86State *env)
|
static int find_real_tpr_addr(VAPICROMState *s, CPUX86State *env)
|
||||||
{
|
{
|
||||||
|
CPUState *cs = CPU(x86_env_get_cpu(env));
|
||||||
hwaddr paddr;
|
hwaddr paddr;
|
||||||
target_ulong addr;
|
target_ulong addr;
|
||||||
|
|
||||||
|
@ -158,7 +159,7 @@ static int find_real_tpr_addr(VAPICROMState *s, CPUX86State *env)
|
||||||
* virtual address space for the APIC mapping.
|
* virtual address space for the APIC mapping.
|
||||||
*/
|
*/
|
||||||
for (addr = 0xfffff000; addr >= 0x80000000; addr -= TARGET_PAGE_SIZE) {
|
for (addr = 0xfffff000; addr >= 0x80000000; addr -= TARGET_PAGE_SIZE) {
|
||||||
paddr = cpu_get_phys_page_debug(env, addr);
|
paddr = cpu_get_phys_page_debug(cs, addr);
|
||||||
if (paddr != APIC_DEFAULT_ADDRESS) {
|
if (paddr != APIC_DEFAULT_ADDRESS) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -187,9 +188,10 @@ static bool opcode_matches(uint8_t *opcode, const TPRInstruction *instr)
|
||||||
modrm_reg(opcode[1]) == instr->modrm_reg);
|
modrm_reg(opcode[1]) == instr->modrm_reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int evaluate_tpr_instruction(VAPICROMState *s, CPUX86State *env,
|
static int evaluate_tpr_instruction(VAPICROMState *s, X86CPU *cpu,
|
||||||
target_ulong *pip, TPRAccess access)
|
target_ulong *pip, TPRAccess access)
|
||||||
{
|
{
|
||||||
|
CPUState *cs = CPU(cpu);
|
||||||
const TPRInstruction *instr;
|
const TPRInstruction *instr;
|
||||||
target_ulong ip = *pip;
|
target_ulong ip = *pip;
|
||||||
uint8_t opcode[2];
|
uint8_t opcode[2];
|
||||||
|
@ -210,7 +212,7 @@ static int evaluate_tpr_instruction(VAPICROMState *s, CPUX86State *env,
|
||||||
* RSP, used by the patched instruction, is zero, so the guest gets a
|
* RSP, used by the patched instruction, is zero, so the guest gets a
|
||||||
* double fault and dies.
|
* double fault and dies.
|
||||||
*/
|
*/
|
||||||
if (env->regs[R_ESP] == 0) {
|
if (cpu->env.regs[R_ESP] == 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,7 +227,7 @@ static int evaluate_tpr_instruction(VAPICROMState *s, CPUX86State *env,
|
||||||
if (instr->access != access) {
|
if (instr->access != access) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (cpu_memory_rw_debug(env, ip - instr->length, opcode,
|
if (cpu_memory_rw_debug(cs, ip - instr->length, opcode,
|
||||||
sizeof(opcode), 0) < 0) {
|
sizeof(opcode), 0) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -236,7 +238,7 @@ static int evaluate_tpr_instruction(VAPICROMState *s, CPUX86State *env,
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
if (cpu_memory_rw_debug(env, ip, opcode, sizeof(opcode), 0) < 0) {
|
if (cpu_memory_rw_debug(cs, ip, opcode, sizeof(opcode), 0) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
for (i = 0; i < ARRAY_SIZE(tpr_instr); i++) {
|
for (i = 0; i < ARRAY_SIZE(tpr_instr); i++) {
|
||||||
|
@ -253,7 +255,7 @@ instruction_ok:
|
||||||
* Grab the virtual TPR address from the instruction
|
* Grab the virtual TPR address from the instruction
|
||||||
* and update the cached values.
|
* and update the cached values.
|
||||||
*/
|
*/
|
||||||
if (cpu_memory_rw_debug(env, ip + instr->addr_offset,
|
if (cpu_memory_rw_debug(cs, ip + instr->addr_offset,
|
||||||
(void *)&real_tpr_addr,
|
(void *)&real_tpr_addr,
|
||||||
sizeof(real_tpr_addr), 0) < 0) {
|
sizeof(real_tpr_addr), 0) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -271,6 +273,7 @@ instruction_ok:
|
||||||
|
|
||||||
static int update_rom_mapping(VAPICROMState *s, CPUX86State *env, target_ulong ip)
|
static int update_rom_mapping(VAPICROMState *s, CPUX86State *env, target_ulong ip)
|
||||||
{
|
{
|
||||||
|
CPUState *cs = CPU(x86_env_get_cpu(env));
|
||||||
hwaddr paddr;
|
hwaddr paddr;
|
||||||
uint32_t rom_state_vaddr;
|
uint32_t rom_state_vaddr;
|
||||||
uint32_t pos, patch, offset;
|
uint32_t pos, patch, offset;
|
||||||
|
@ -287,7 +290,7 @@ static int update_rom_mapping(VAPICROMState *s, CPUX86State *env, target_ulong i
|
||||||
|
|
||||||
/* find out virtual address of the ROM */
|
/* find out virtual address of the ROM */
|
||||||
rom_state_vaddr = s->rom_state_paddr + (ip & 0xf0000000);
|
rom_state_vaddr = s->rom_state_paddr + (ip & 0xf0000000);
|
||||||
paddr = cpu_get_phys_page_debug(env, rom_state_vaddr);
|
paddr = cpu_get_phys_page_debug(cs, rom_state_vaddr);
|
||||||
if (paddr == -1) {
|
if (paddr == -1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -332,8 +335,9 @@ static int update_rom_mapping(VAPICROMState *s, CPUX86State *env, target_ulong i
|
||||||
* cannot be accessed or is considered invalid. This also ensures that we are
|
* cannot be accessed or is considered invalid. This also ensures that we are
|
||||||
* not patching the wrong guest.
|
* not patching the wrong guest.
|
||||||
*/
|
*/
|
||||||
static int get_kpcr_number(CPUX86State *env)
|
static int get_kpcr_number(X86CPU *cpu)
|
||||||
{
|
{
|
||||||
|
CPUX86State *env = &cpu->env;
|
||||||
struct kpcr {
|
struct kpcr {
|
||||||
uint8_t fill1[0x1c];
|
uint8_t fill1[0x1c];
|
||||||
uint32_t self;
|
uint32_t self;
|
||||||
|
@ -341,7 +345,7 @@ static int get_kpcr_number(CPUX86State *env)
|
||||||
uint8_t number;
|
uint8_t number;
|
||||||
} QEMU_PACKED kpcr;
|
} QEMU_PACKED kpcr;
|
||||||
|
|
||||||
if (cpu_memory_rw_debug(env, env->segs[R_FS].base,
|
if (cpu_memory_rw_debug(CPU(cpu), env->segs[R_FS].base,
|
||||||
(void *)&kpcr, sizeof(kpcr), 0) < 0 ||
|
(void *)&kpcr, sizeof(kpcr), 0) < 0 ||
|
||||||
kpcr.self != env->segs[R_FS].base) {
|
kpcr.self != env->segs[R_FS].base) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -349,9 +353,9 @@ static int get_kpcr_number(CPUX86State *env)
|
||||||
return kpcr.number;
|
return kpcr.number;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vapic_enable(VAPICROMState *s, CPUX86State *env)
|
static int vapic_enable(VAPICROMState *s, X86CPU *cpu)
|
||||||
{
|
{
|
||||||
int cpu_number = get_kpcr_number(env);
|
int cpu_number = get_kpcr_number(cpu);
|
||||||
hwaddr vapic_paddr;
|
hwaddr vapic_paddr;
|
||||||
static const uint8_t enabled = 1;
|
static const uint8_t enabled = 1;
|
||||||
|
|
||||||
|
@ -362,26 +366,26 @@ static int vapic_enable(VAPICROMState *s, CPUX86State *env)
|
||||||
(((hwaddr)cpu_number) << VAPIC_CPU_SHIFT);
|
(((hwaddr)cpu_number) << VAPIC_CPU_SHIFT);
|
||||||
cpu_physical_memory_rw(vapic_paddr + offsetof(VAPICState, enabled),
|
cpu_physical_memory_rw(vapic_paddr + offsetof(VAPICState, enabled),
|
||||||
(void *)&enabled, sizeof(enabled), 1);
|
(void *)&enabled, sizeof(enabled), 1);
|
||||||
apic_enable_vapic(env->apic_state, vapic_paddr);
|
apic_enable_vapic(cpu->env.apic_state, vapic_paddr);
|
||||||
|
|
||||||
s->state = VAPIC_ACTIVE;
|
s->state = VAPIC_ACTIVE;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void patch_byte(CPUX86State *env, target_ulong addr, uint8_t byte)
|
static void patch_byte(X86CPU *cpu, target_ulong addr, uint8_t byte)
|
||||||
{
|
{
|
||||||
cpu_memory_rw_debug(env, addr, &byte, 1, 1);
|
cpu_memory_rw_debug(CPU(cpu), addr, &byte, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void patch_call(VAPICROMState *s, CPUX86State *env, target_ulong ip,
|
static void patch_call(VAPICROMState *s, X86CPU *cpu, target_ulong ip,
|
||||||
uint32_t target)
|
uint32_t target)
|
||||||
{
|
{
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
|
|
||||||
offset = cpu_to_le32(target - ip - 5);
|
offset = cpu_to_le32(target - ip - 5);
|
||||||
patch_byte(env, ip, 0xe8); /* call near */
|
patch_byte(cpu, ip, 0xe8); /* call near */
|
||||||
cpu_memory_rw_debug(env, ip + 1, (void *)&offset, sizeof(offset), 1);
|
cpu_memory_rw_debug(CPU(cpu), ip + 1, (void *)&offset, sizeof(offset), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
|
static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
|
||||||
|
@ -409,32 +413,32 @@ static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
|
||||||
|
|
||||||
pause_all_vcpus();
|
pause_all_vcpus();
|
||||||
|
|
||||||
cpu_memory_rw_debug(env, ip, opcode, sizeof(opcode), 0);
|
cpu_memory_rw_debug(cs, ip, opcode, sizeof(opcode), 0);
|
||||||
|
|
||||||
switch (opcode[0]) {
|
switch (opcode[0]) {
|
||||||
case 0x89: /* mov r32 to r/m32 */
|
case 0x89: /* mov r32 to r/m32 */
|
||||||
patch_byte(env, ip, 0x50 + modrm_reg(opcode[1])); /* push reg */
|
patch_byte(cpu, ip, 0x50 + modrm_reg(opcode[1])); /* push reg */
|
||||||
patch_call(s, env, ip + 1, handlers->set_tpr);
|
patch_call(s, cpu, ip + 1, handlers->set_tpr);
|
||||||
break;
|
break;
|
||||||
case 0x8b: /* mov r/m32 to r32 */
|
case 0x8b: /* mov r/m32 to r32 */
|
||||||
patch_byte(env, ip, 0x90);
|
patch_byte(cpu, ip, 0x90);
|
||||||
patch_call(s, env, ip + 1, handlers->get_tpr[modrm_reg(opcode[1])]);
|
patch_call(s, cpu, ip + 1, handlers->get_tpr[modrm_reg(opcode[1])]);
|
||||||
break;
|
break;
|
||||||
case 0xa1: /* mov abs to eax */
|
case 0xa1: /* mov abs to eax */
|
||||||
patch_call(s, env, ip, handlers->get_tpr[0]);
|
patch_call(s, cpu, ip, handlers->get_tpr[0]);
|
||||||
break;
|
break;
|
||||||
case 0xa3: /* mov eax to abs */
|
case 0xa3: /* mov eax to abs */
|
||||||
patch_call(s, env, ip, handlers->set_tpr_eax);
|
patch_call(s, cpu, ip, handlers->set_tpr_eax);
|
||||||
break;
|
break;
|
||||||
case 0xc7: /* mov imm32, r/m32 (c7/0) */
|
case 0xc7: /* mov imm32, r/m32 (c7/0) */
|
||||||
patch_byte(env, ip, 0x68); /* push imm32 */
|
patch_byte(cpu, ip, 0x68); /* push imm32 */
|
||||||
cpu_memory_rw_debug(env, ip + 6, (void *)&imm32, sizeof(imm32), 0);
|
cpu_memory_rw_debug(cs, ip + 6, (void *)&imm32, sizeof(imm32), 0);
|
||||||
cpu_memory_rw_debug(env, ip + 1, (void *)&imm32, sizeof(imm32), 1);
|
cpu_memory_rw_debug(cs, ip + 1, (void *)&imm32, sizeof(imm32), 1);
|
||||||
patch_call(s, env, ip + 5, handlers->set_tpr);
|
patch_call(s, cpu, ip + 5, handlers->set_tpr);
|
||||||
break;
|
break;
|
||||||
case 0xff: /* push r/m32 */
|
case 0xff: /* push r/m32 */
|
||||||
patch_byte(env, ip, 0x50); /* push eax */
|
patch_byte(cpu, ip, 0x50); /* push eax */
|
||||||
patch_call(s, env, ip + 1, handlers->get_tpr_stack);
|
patch_call(s, cpu, ip + 1, handlers->get_tpr_stack);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
abort();
|
abort();
|
||||||
|
@ -458,16 +462,16 @@ void vapic_report_tpr_access(DeviceState *dev, CPUState *cs, target_ulong ip,
|
||||||
|
|
||||||
cpu_synchronize_state(cs);
|
cpu_synchronize_state(cs);
|
||||||
|
|
||||||
if (evaluate_tpr_instruction(s, env, &ip, access) < 0) {
|
if (evaluate_tpr_instruction(s, cpu, &ip, access) < 0) {
|
||||||
if (s->state == VAPIC_ACTIVE) {
|
if (s->state == VAPIC_ACTIVE) {
|
||||||
vapic_enable(s, env);
|
vapic_enable(s, cpu);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (update_rom_mapping(s, env, ip) < 0) {
|
if (update_rom_mapping(s, env, ip) < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (vapic_enable(s, env) < 0) {
|
if (vapic_enable(s, cpu) < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
patch_instruction(s, cpu, ip);
|
patch_instruction(s, cpu, ip);
|
||||||
|
@ -667,8 +671,8 @@ static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
|
||||||
* accurate.
|
* accurate.
|
||||||
*/
|
*/
|
||||||
pause_all_vcpus();
|
pause_all_vcpus();
|
||||||
patch_byte(env, env->eip - 2, 0x66);
|
patch_byte(cpu, env->eip - 2, 0x66);
|
||||||
patch_byte(env, env->eip - 1, 0x90);
|
patch_byte(cpu, env->eip - 1, 0x90);
|
||||||
resume_all_vcpus();
|
resume_all_vcpus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -681,7 +685,7 @@ static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
|
||||||
if (find_real_tpr_addr(s, env) < 0) {
|
if (find_real_tpr_addr(s, env) < 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
vapic_enable(s, env);
|
vapic_enable(s, cpu);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
case 4:
|
case 4:
|
||||||
|
@ -722,7 +726,7 @@ static void do_vapic_enable(void *data)
|
||||||
VAPICROMState *s = data;
|
VAPICROMState *s = data;
|
||||||
X86CPU *cpu = X86_CPU(first_cpu);
|
X86CPU *cpu = X86_CPU(first_cpu);
|
||||||
|
|
||||||
vapic_enable(s, &cpu->env);
|
vapic_enable(s, cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vapic_post_load(void *opaque, int version_id)
|
static int vapic_post_load(void *opaque, int version_id)
|
||||||
|
|
|
@ -144,9 +144,11 @@ static void lx60_net_init(MemoryRegion *address_space,
|
||||||
memory_region_add_subregion(address_space, buffers, ram);
|
memory_region_add_subregion(address_space, buffers, ram);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t translate_phys_addr(void *env, uint64_t addr)
|
static uint64_t translate_phys_addr(void *opaque, uint64_t addr)
|
||||||
{
|
{
|
||||||
return cpu_get_phys_page_debug(env, addr);
|
XtensaCPU *cpu = opaque;
|
||||||
|
|
||||||
|
return cpu_get_phys_page_debug(CPU(cpu), addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lx60_reset(void *opaque)
|
static void lx60_reset(void *opaque)
|
||||||
|
@ -252,7 +254,7 @@ static void lx_init(const LxBoardDesc *board, QEMUMachineInitArgs *args)
|
||||||
}
|
}
|
||||||
uint64_t elf_entry;
|
uint64_t elf_entry;
|
||||||
uint64_t elf_lowaddr;
|
uint64_t elf_lowaddr;
|
||||||
int success = load_elf(kernel_filename, translate_phys_addr, env,
|
int success = load_elf(kernel_filename, translate_phys_addr, cpu,
|
||||||
&elf_entry, &elf_lowaddr, NULL, be, ELF_MACHINE, 0);
|
&elf_entry, &elf_lowaddr, NULL, be, ELF_MACHINE, 0);
|
||||||
if (success > 0) {
|
if (success > 0) {
|
||||||
env->pc = elf_entry;
|
env->pc = elf_entry;
|
||||||
|
|
|
@ -32,9 +32,11 @@
|
||||||
#include "exec/memory.h"
|
#include "exec/memory.h"
|
||||||
#include "exec/address-spaces.h"
|
#include "exec/address-spaces.h"
|
||||||
|
|
||||||
static uint64_t translate_phys_addr(void *env, uint64_t addr)
|
static uint64_t translate_phys_addr(void *opaque, uint64_t addr)
|
||||||
{
|
{
|
||||||
return cpu_get_phys_page_debug(env, addr);
|
XtensaCPU *cpu = opaque;
|
||||||
|
|
||||||
|
return cpu_get_phys_page_debug(CPU(cpu), addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sim_reset(void *opaque)
|
static void sim_reset(void *opaque)
|
||||||
|
@ -88,10 +90,10 @@ static void xtensa_sim_init(QEMUMachineInitArgs *args)
|
||||||
uint64_t elf_entry;
|
uint64_t elf_entry;
|
||||||
uint64_t elf_lowaddr;
|
uint64_t elf_lowaddr;
|
||||||
#ifdef TARGET_WORDS_BIGENDIAN
|
#ifdef TARGET_WORDS_BIGENDIAN
|
||||||
int success = load_elf(kernel_filename, translate_phys_addr, env,
|
int success = load_elf(kernel_filename, translate_phys_addr, cpu,
|
||||||
&elf_entry, &elf_lowaddr, NULL, 1, ELF_MACHINE, 0);
|
&elf_entry, &elf_lowaddr, NULL, 1, ELF_MACHINE, 0);
|
||||||
#else
|
#else
|
||||||
int success = load_elf(kernel_filename, translate_phys_addr, env,
|
int success = load_elf(kernel_filename, translate_phys_addr, cpu,
|
||||||
&elf_entry, &elf_lowaddr, NULL, 0, ELF_MACHINE, 0);
|
&elf_entry, &elf_lowaddr, NULL, 0, ELF_MACHINE, 0);
|
||||||
#endif
|
#endif
|
||||||
if (success > 0) {
|
if (success > 0) {
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "exec/cpu-common.h"
|
#include "exec/cpu-common.h"
|
||||||
#include "qemu/thread.h"
|
#include "qemu/thread.h"
|
||||||
|
#include "qom/cpu.h"
|
||||||
|
|
||||||
/* some important defines:
|
/* some important defines:
|
||||||
*
|
*
|
||||||
|
@ -428,19 +429,8 @@ int cpu_watchpoint_remove(CPUArchState *env, target_ulong addr,
|
||||||
void cpu_watchpoint_remove_by_ref(CPUArchState *env, CPUWatchpoint *watchpoint);
|
void cpu_watchpoint_remove_by_ref(CPUArchState *env, CPUWatchpoint *watchpoint);
|
||||||
void cpu_watchpoint_remove_all(CPUArchState *env, int mask);
|
void cpu_watchpoint_remove_all(CPUArchState *env, int mask);
|
||||||
|
|
||||||
#define SSTEP_ENABLE 0x1 /* Enable simulated HW single stepping */
|
|
||||||
#define SSTEP_NOIRQ 0x2 /* Do not use IRQ while single stepping */
|
|
||||||
#define SSTEP_NOTIMER 0x4 /* Do not Timers while single stepping */
|
|
||||||
|
|
||||||
void cpu_single_step(CPUArchState *env, int enabled);
|
|
||||||
|
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
|
|
||||||
/* Return the physical page corresponding to a virtual one. Use it
|
|
||||||
only for debugging because no protection checks are done. Return -1
|
|
||||||
if no page found. */
|
|
||||||
hwaddr cpu_get_phys_page_debug(CPUArchState *env, target_ulong addr);
|
|
||||||
|
|
||||||
/* memory API */
|
/* memory API */
|
||||||
|
|
||||||
extern ram_addr_t ram_size;
|
extern ram_addr_t ram_size;
|
||||||
|
@ -494,7 +484,7 @@ void qemu_mutex_lock_ramlist(void);
|
||||||
void qemu_mutex_unlock_ramlist(void);
|
void qemu_mutex_unlock_ramlist(void);
|
||||||
#endif /* !CONFIG_USER_ONLY */
|
#endif /* !CONFIG_USER_ONLY */
|
||||||
|
|
||||||
int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,
|
int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
|
||||||
uint8_t *buf, int len, int is_write);
|
uint8_t *buf, int len, int is_write);
|
||||||
|
|
||||||
#endif /* CPU_ALL_H */
|
#endif /* CPU_ALL_H */
|
||||||
|
|
|
@ -170,13 +170,10 @@ typedef struct CPUWatchpoint {
|
||||||
/* from this point: preserved by CPU reset */ \
|
/* from this point: preserved by CPU reset */ \
|
||||||
/* ice debug support */ \
|
/* ice debug support */ \
|
||||||
QTAILQ_HEAD(breakpoints_head, CPUBreakpoint) breakpoints; \
|
QTAILQ_HEAD(breakpoints_head, CPUBreakpoint) breakpoints; \
|
||||||
int singlestep_enabled; \
|
|
||||||
\
|
\
|
||||||
QTAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints; \
|
QTAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints; \
|
||||||
CPUWatchpoint *watchpoint_hit; \
|
CPUWatchpoint *watchpoint_hit; \
|
||||||
\
|
\
|
||||||
struct GDBRegisterState *gdb_regs; \
|
|
||||||
\
|
|
||||||
/* Core interrupt code */ \
|
/* Core interrupt code */ \
|
||||||
sigjmp_buf jmp_env; \
|
sigjmp_buf jmp_env; \
|
||||||
int exception_index; \
|
int exception_index; \
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#define GDB_WATCHPOINT_ACCESS 4
|
#define GDB_WATCHPOINT_ACCESS 4
|
||||||
|
|
||||||
#ifdef NEED_CPU_H
|
#ifdef NEED_CPU_H
|
||||||
typedef void (*gdb_syscall_complete_cb)(CPUArchState *env,
|
typedef void (*gdb_syscall_complete_cb)(CPUState *cpu,
|
||||||
target_ulong ret, target_ulong err);
|
target_ulong ret, target_ulong err);
|
||||||
|
|
||||||
void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...);
|
void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...);
|
||||||
|
@ -20,13 +20,13 @@ void gdb_set_stop_cpu(CPUState *cpu);
|
||||||
void gdb_exit(CPUArchState *, int);
|
void gdb_exit(CPUArchState *, int);
|
||||||
#ifdef CONFIG_USER_ONLY
|
#ifdef CONFIG_USER_ONLY
|
||||||
int gdb_queuesig (void);
|
int gdb_queuesig (void);
|
||||||
int gdb_handlesig (CPUArchState *, int);
|
int gdb_handlesig(CPUState *, int);
|
||||||
void gdb_signalled(CPUArchState *, int);
|
void gdb_signalled(CPUArchState *, int);
|
||||||
void gdbserver_fork(CPUArchState *);
|
void gdbserver_fork(CPUArchState *);
|
||||||
#endif
|
#endif
|
||||||
/* Get or set a register. Returns the size of the register. */
|
/* Get or set a register. Returns the size of the register. */
|
||||||
typedef int (*gdb_reg_cb)(CPUArchState *env, uint8_t *buf, int reg);
|
typedef int (*gdb_reg_cb)(CPUArchState *env, uint8_t *buf, int reg);
|
||||||
void gdb_register_coprocessor(CPUArchState *env,
|
void gdb_register_coprocessor(CPUState *cpu,
|
||||||
gdb_reg_cb get_reg, gdb_reg_cb set_reg,
|
gdb_reg_cb get_reg, gdb_reg_cb set_reg,
|
||||||
int num_regs, const char *xml, int g_pos);
|
int num_regs, const char *xml, int g_pos);
|
||||||
|
|
||||||
|
|
|
@ -13,14 +13,14 @@ static inline uint32_t softmmu_tget32(CPUArchState *env, uint32_t addr)
|
||||||
{
|
{
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
|
|
||||||
cpu_memory_rw_debug(env, addr, (uint8_t *)&val, 4, 0);
|
cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)&val, 4, 0);
|
||||||
return tswap32(val);
|
return tswap32(val);
|
||||||
}
|
}
|
||||||
static inline uint32_t softmmu_tget8(CPUArchState *env, uint32_t addr)
|
static inline uint32_t softmmu_tget8(CPUArchState *env, uint32_t addr)
|
||||||
{
|
{
|
||||||
uint8_t val;
|
uint8_t val;
|
||||||
|
|
||||||
cpu_memory_rw_debug(env, addr, &val, 1, 0);
|
cpu_memory_rw_debug(ENV_GET_CPU(env), addr, &val, 1, 0);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ static inline uint32_t softmmu_tget8(CPUArchState *env, uint32_t addr)
|
||||||
static inline void softmmu_tput32(CPUArchState *env, uint32_t addr, uint32_t val)
|
static inline void softmmu_tput32(CPUArchState *env, uint32_t addr, uint32_t val)
|
||||||
{
|
{
|
||||||
val = tswap32(val);
|
val = tswap32(val);
|
||||||
cpu_memory_rw_debug(env, addr, (uint8_t *)&val, 4, 1);
|
cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)&val, 4, 1);
|
||||||
}
|
}
|
||||||
#define put_user_u32(arg, p) ({ softmmu_tput32(env, p, arg) ; 0; })
|
#define put_user_u32(arg, p) ({ softmmu_tput32(env, p, arg) ; 0; })
|
||||||
#define put_user_ual(arg, p) put_user_u32(arg, p)
|
#define put_user_ual(arg, p) put_user_u32(arg, p)
|
||||||
|
@ -42,8 +42,9 @@ static void *softmmu_lock_user(CPUArchState *env, uint32_t addr, uint32_t len,
|
||||||
uint8_t *p;
|
uint8_t *p;
|
||||||
/* TODO: Make this something that isn't fixed size. */
|
/* TODO: Make this something that isn't fixed size. */
|
||||||
p = malloc(len);
|
p = malloc(len);
|
||||||
if (p && copy)
|
if (p && copy) {
|
||||||
cpu_memory_rw_debug(env, addr, p, len, 0);
|
cpu_memory_rw_debug(ENV_GET_CPU(env), addr, p, len, 0);
|
||||||
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
#define lock_user(type, p, len, copy) softmmu_lock_user(env, p, len, copy)
|
#define lock_user(type, p, len, copy) softmmu_lock_user(env, p, len, copy)
|
||||||
|
@ -58,7 +59,7 @@ static char *softmmu_lock_user_string(CPUArchState *env, uint32_t addr)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
cpu_memory_rw_debug(env, addr, &c, 1, 0);
|
cpu_memory_rw_debug(ENV_GET_CPU(env), addr, &c, 1, 0);
|
||||||
addr++;
|
addr++;
|
||||||
*(p++) = c;
|
*(p++) = c;
|
||||||
} while (c);
|
} while (c);
|
||||||
|
@ -68,8 +69,9 @@ static char *softmmu_lock_user_string(CPUArchState *env, uint32_t addr)
|
||||||
static void softmmu_unlock_user(CPUArchState *env, void *p, target_ulong addr,
|
static void softmmu_unlock_user(CPUArchState *env, void *p, target_ulong addr,
|
||||||
target_ulong len)
|
target_ulong len)
|
||||||
{
|
{
|
||||||
if (len)
|
if (len) {
|
||||||
cpu_memory_rw_debug(env, addr, p, len, 1);
|
cpu_memory_rw_debug(ENV_GET_CPU(env), addr, p, len, 1);
|
||||||
|
}
|
||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
#define unlock_user(s, args, len) softmmu_unlock_user(env, s, args, len)
|
#define unlock_user(s, args, len) softmmu_unlock_user(env, s, args, len)
|
||||||
|
|
|
@ -29,6 +29,18 @@
|
||||||
|
|
||||||
typedef int (*WriteCoreDumpFunction)(void *buf, size_t size, void *opaque);
|
typedef int (*WriteCoreDumpFunction)(void *buf, size_t size, void *opaque);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vaddr:
|
||||||
|
* Type wide enough to contain any #target_ulong virtual address.
|
||||||
|
*/
|
||||||
|
typedef uint64_t vaddr;
|
||||||
|
#define VADDR_PRId PRId64
|
||||||
|
#define VADDR_PRIu PRIu64
|
||||||
|
#define VADDR_PRIo PRIo64
|
||||||
|
#define VADDR_PRIx PRIx64
|
||||||
|
#define VADDR_PRIX PRIX64
|
||||||
|
#define VADDR_MAX UINT64_MAX
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:cpu
|
* SECTION:cpu
|
||||||
* @section_id: QEMU-cpu
|
* @section_id: QEMU-cpu
|
||||||
|
@ -48,6 +60,8 @@ typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr,
|
||||||
bool is_write, bool is_exec, int opaque,
|
bool is_write, bool is_exec, int opaque,
|
||||||
unsigned size);
|
unsigned size);
|
||||||
|
|
||||||
|
struct TranslationBlock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CPUClass:
|
* CPUClass:
|
||||||
* @class_by_name: Callback to map -cpu command line model name to an
|
* @class_by_name: Callback to map -cpu command line model name to an
|
||||||
|
@ -56,11 +70,16 @@ typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr,
|
||||||
* @reset_dump_flags: #CPUDumpFlags to use for reset logging.
|
* @reset_dump_flags: #CPUDumpFlags to use for reset logging.
|
||||||
* @do_interrupt: Callback for interrupt handling.
|
* @do_interrupt: Callback for interrupt handling.
|
||||||
* @do_unassigned_access: Callback for unassigned access handling.
|
* @do_unassigned_access: Callback for unassigned access handling.
|
||||||
|
* @memory_rw_debug: Callback for GDB memory access.
|
||||||
* @dump_state: Callback for dumping state.
|
* @dump_state: Callback for dumping state.
|
||||||
* @dump_statistics: Callback for dumping statistics.
|
* @dump_statistics: Callback for dumping statistics.
|
||||||
* @get_arch_id: Callback for getting architecture-dependent CPU ID.
|
* @get_arch_id: Callback for getting architecture-dependent CPU ID.
|
||||||
* @get_paging_enabled: Callback for inquiring whether paging is enabled.
|
* @get_paging_enabled: Callback for inquiring whether paging is enabled.
|
||||||
* @get_memory_mapping: Callback for obtaining the memory mappings.
|
* @get_memory_mapping: Callback for obtaining the memory mappings.
|
||||||
|
* @set_pc: Callback for setting the Program Counter register.
|
||||||
|
* @synchronize_from_tb: Callback for synchronizing state from a TCG
|
||||||
|
* #TranslationBlock.
|
||||||
|
* @get_phys_page_debug: Callback for obtaining a physical address.
|
||||||
* @vmsd: State description for migration.
|
* @vmsd: State description for migration.
|
||||||
*
|
*
|
||||||
* Represents a CPU family or model.
|
* Represents a CPU family or model.
|
||||||
|
@ -76,6 +95,8 @@ typedef struct CPUClass {
|
||||||
int reset_dump_flags;
|
int reset_dump_flags;
|
||||||
void (*do_interrupt)(CPUState *cpu);
|
void (*do_interrupt)(CPUState *cpu);
|
||||||
CPUUnassignedAccess do_unassigned_access;
|
CPUUnassignedAccess do_unassigned_access;
|
||||||
|
int (*memory_rw_debug)(CPUState *cpu, vaddr addr,
|
||||||
|
uint8_t *buf, int len, bool is_write);
|
||||||
void (*dump_state)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
|
void (*dump_state)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
|
||||||
int flags);
|
int flags);
|
||||||
void (*dump_statistics)(CPUState *cpu, FILE *f,
|
void (*dump_statistics)(CPUState *cpu, FILE *f,
|
||||||
|
@ -84,6 +105,9 @@ typedef struct CPUClass {
|
||||||
bool (*get_paging_enabled)(const CPUState *cpu);
|
bool (*get_paging_enabled)(const CPUState *cpu);
|
||||||
void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list,
|
void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
|
void (*set_pc)(CPUState *cpu, vaddr value);
|
||||||
|
void (*synchronize_from_tb)(CPUState *cpu, struct TranslationBlock *tb);
|
||||||
|
hwaddr (*get_phys_page_debug)(CPUState *cpu, vaddr addr);
|
||||||
|
|
||||||
const struct VMStateDescription *vmsd;
|
const struct VMStateDescription *vmsd;
|
||||||
int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu,
|
int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu,
|
||||||
|
@ -114,8 +138,10 @@ struct kvm_run;
|
||||||
* @stopped: Indicates the CPU has been artificially stopped.
|
* @stopped: Indicates the CPU has been artificially stopped.
|
||||||
* @tcg_exit_req: Set to force TCG to stop executing linked TBs for this
|
* @tcg_exit_req: Set to force TCG to stop executing linked TBs for this
|
||||||
* CPU and return to its top level loop.
|
* CPU and return to its top level loop.
|
||||||
|
* @singlestep_enabled: Flags for single-stepping.
|
||||||
* @env_ptr: Pointer to subclass-specific CPUArchState field.
|
* @env_ptr: Pointer to subclass-specific CPUArchState field.
|
||||||
* @current_tb: Currently executing TB.
|
* @current_tb: Currently executing TB.
|
||||||
|
* @gdb_regs: Additional GDB registers.
|
||||||
* @next_cpu: Next CPU sharing TB cache.
|
* @next_cpu: Next CPU sharing TB cache.
|
||||||
* @kvm_fd: vCPU file descriptor for KVM.
|
* @kvm_fd: vCPU file descriptor for KVM.
|
||||||
*
|
*
|
||||||
|
@ -146,9 +172,11 @@ struct CPUState {
|
||||||
volatile sig_atomic_t exit_request;
|
volatile sig_atomic_t exit_request;
|
||||||
volatile sig_atomic_t tcg_exit_req;
|
volatile sig_atomic_t tcg_exit_req;
|
||||||
uint32_t interrupt_request;
|
uint32_t interrupt_request;
|
||||||
|
int singlestep_enabled;
|
||||||
|
|
||||||
void *env_ptr; /* CPUArchState */
|
void *env_ptr; /* CPUArchState */
|
||||||
struct TranslationBlock *current_tb;
|
struct TranslationBlock *current_tb;
|
||||||
|
struct GDBRegisterState *gdb_regs;
|
||||||
CPUState *next_cpu;
|
CPUState *next_cpu;
|
||||||
|
|
||||||
int kvm_fd;
|
int kvm_fd;
|
||||||
|
@ -259,6 +287,25 @@ void cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
|
||||||
void cpu_dump_statistics(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
|
void cpu_dump_statistics(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
|
||||||
int flags);
|
int flags);
|
||||||
|
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
/**
|
||||||
|
* cpu_get_phys_page_debug:
|
||||||
|
* @cpu: The CPU to obtain the physical page address for.
|
||||||
|
* @addr: The virtual address.
|
||||||
|
*
|
||||||
|
* Obtains the physical page corresponding to a virtual one.
|
||||||
|
* Use it only for debugging because no protection checks are done.
|
||||||
|
*
|
||||||
|
* Returns: Corresponding physical page address or -1 if no page found.
|
||||||
|
*/
|
||||||
|
static inline hwaddr cpu_get_phys_page_debug(CPUState *cpu, vaddr addr)
|
||||||
|
{
|
||||||
|
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||||
|
|
||||||
|
return cc->get_phys_page_debug(cpu, addr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cpu_reset:
|
* cpu_reset:
|
||||||
* @cpu: The CPU whose state is to be reset.
|
* @cpu: The CPU whose state is to be reset.
|
||||||
|
@ -276,59 +323,6 @@ void cpu_reset(CPUState *cpu);
|
||||||
*/
|
*/
|
||||||
ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model);
|
ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model);
|
||||||
|
|
||||||
/**
|
|
||||||
* cpu_class_set_vmsd:
|
|
||||||
* @cc: CPU class
|
|
||||||
* @value: Value to set. Unused for %CONFIG_USER_ONLY.
|
|
||||||
*
|
|
||||||
* Sets #VMStateDescription for @cc.
|
|
||||||
*
|
|
||||||
* The @value argument is intentionally discarded for the non-softmmu targets
|
|
||||||
* to avoid linker errors or excessive preprocessor usage. If this behavior
|
|
||||||
* is undesired, you should assign #CPUClass.vmsd directly instead.
|
|
||||||
*/
|
|
||||||
#ifndef CONFIG_USER_ONLY
|
|
||||||
static inline void cpu_class_set_vmsd(CPUClass *cc,
|
|
||||||
const struct VMStateDescription *value)
|
|
||||||
{
|
|
||||||
cc->vmsd = value;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define cpu_class_set_vmsd(cc, value) ((cc)->vmsd = NULL)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CONFIG_USER_ONLY
|
|
||||||
static inline void cpu_class_set_do_unassigned_access(CPUClass *cc,
|
|
||||||
CPUUnassignedAccess value)
|
|
||||||
{
|
|
||||||
cc->do_unassigned_access = value;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define cpu_class_set_do_unassigned_access(cc, value) \
|
|
||||||
((cc)->do_unassigned_access = NULL)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* device_class_set_vmsd:
|
|
||||||
* @dc: Device class
|
|
||||||
* @value: Value to set. Unused for %CONFIG_USER_ONLY.
|
|
||||||
*
|
|
||||||
* Sets #VMStateDescription for @dc.
|
|
||||||
*
|
|
||||||
* The @value argument is intentionally discarded for the non-softmmu targets
|
|
||||||
* to avoid linker errors or excessive preprocessor usage. If this behavior
|
|
||||||
* is undesired, you should assign #DeviceClass.vmsd directly instead.
|
|
||||||
*/
|
|
||||||
#ifndef CONFIG_USER_ONLY
|
|
||||||
static inline void device_class_set_vmsd(DeviceClass *dc,
|
|
||||||
const struct VMStateDescription *value)
|
|
||||||
{
|
|
||||||
dc->vmsd = value;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define device_class_set_vmsd(dc, value) ((dc)->vmsd = NULL)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qemu_cpu_has_work:
|
* qemu_cpu_has_work:
|
||||||
* @cpu: The vCPU to check.
|
* @cpu: The vCPU to check.
|
||||||
|
@ -489,6 +483,19 @@ void cpu_resume(CPUState *cpu);
|
||||||
*/
|
*/
|
||||||
void qemu_init_vcpu(CPUState *cpu);
|
void qemu_init_vcpu(CPUState *cpu);
|
||||||
|
|
||||||
|
#define SSTEP_ENABLE 0x1 /* Enable simulated HW single stepping */
|
||||||
|
#define SSTEP_NOIRQ 0x2 /* Do not use IRQ while single stepping */
|
||||||
|
#define SSTEP_NOTIMER 0x4 /* Do not Timers while single stepping */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cpu_single_step:
|
||||||
|
* @cpu: CPU to the flags for.
|
||||||
|
* @enabled: Flags to enable.
|
||||||
|
*
|
||||||
|
* Enables or disables single-stepping for @cpu.
|
||||||
|
*/
|
||||||
|
void cpu_single_step(CPUState *cpu, int enabled);
|
||||||
|
|
||||||
#ifdef CONFIG_SOFTMMU
|
#ifdef CONFIG_SOFTMMU
|
||||||
extern const struct VMStateDescription vmstate_cpu_common;
|
extern const struct VMStateDescription vmstate_cpu_common;
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -169,9 +169,9 @@ void *kvm_arch_ram_alloc(ram_addr_t size);
|
||||||
void kvm_setup_guest_memory(void *start, size_t size);
|
void kvm_setup_guest_memory(void *start, size_t size);
|
||||||
void kvm_flush_coalesced_mmio_buffer(void);
|
void kvm_flush_coalesced_mmio_buffer(void);
|
||||||
|
|
||||||
int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
|
int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr,
|
||||||
target_ulong len, int type);
|
target_ulong len, int type);
|
||||||
int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
|
int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr,
|
||||||
target_ulong len, int type);
|
target_ulong len, int type);
|
||||||
void kvm_remove_all_breakpoints(CPUState *cpu);
|
void kvm_remove_all_breakpoints(CPUState *cpu);
|
||||||
int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap);
|
int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap);
|
||||||
|
|
12
kvm-all.c
12
kvm-all.c
|
@ -1890,7 +1890,7 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
|
||||||
|
|
||||||
data.dbg.control = reinject_trap;
|
data.dbg.control = reinject_trap;
|
||||||
|
|
||||||
if (env->singlestep_enabled) {
|
if (cpu->singlestep_enabled) {
|
||||||
data.dbg.control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP;
|
data.dbg.control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP;
|
||||||
}
|
}
|
||||||
kvm_arch_update_guest_debug(cpu, &data.dbg);
|
kvm_arch_update_guest_debug(cpu, &data.dbg);
|
||||||
|
@ -1900,10 +1900,9 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
|
||||||
return data.err;
|
return data.err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
|
int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr,
|
||||||
target_ulong len, int type)
|
target_ulong len, int type)
|
||||||
{
|
{
|
||||||
CPUState *cpu = ENV_GET_CPU(env);
|
|
||||||
struct kvm_sw_breakpoint *bp;
|
struct kvm_sw_breakpoint *bp;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -1946,10 +1945,9 @@ int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
|
int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr,
|
||||||
target_ulong len, int type)
|
target_ulong len, int type)
|
||||||
{
|
{
|
||||||
CPUState *cpu = ENV_GET_CPU(env);
|
|
||||||
struct kvm_sw_breakpoint *bp;
|
struct kvm_sw_breakpoint *bp;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -2022,13 +2020,13 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
|
int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr,
|
||||||
target_ulong len, int type)
|
target_ulong len, int type)
|
||||||
{
|
{
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
|
int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr,
|
||||||
target_ulong len, int type)
|
target_ulong len, int type)
|
||||||
{
|
{
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -83,13 +83,13 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
|
int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr,
|
||||||
target_ulong len, int type)
|
target_ulong len, int type)
|
||||||
{
|
{
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
|
int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr,
|
||||||
target_ulong len, int type)
|
target_ulong len, int type)
|
||||||
{
|
{
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -55,12 +55,14 @@ const char *cpu_to_uname_machine(void *cpu_env)
|
||||||
return "x86-64";
|
return "x86-64";
|
||||||
#elif defined(TARGET_I386)
|
#elif defined(TARGET_I386)
|
||||||
/* see arch/x86/kernel/cpu/bugs.c: check_bugs(), 386, 486, 586, 686 */
|
/* see arch/x86/kernel/cpu/bugs.c: check_bugs(), 386, 486, 586, 686 */
|
||||||
uint32_t cpuid_version = ((CPUX86State *)cpu_env)->cpuid_version;
|
CPUState *cpu = ENV_GET_CPU((CPUX86State *)cpu_env);
|
||||||
int family = ((cpuid_version >> 8) & 0x0f) + ((cpuid_version >> 20) & 0xff);
|
int family = object_property_get_int(OBJECT(cpu), "family", NULL);
|
||||||
if (family == 4)
|
if (family == 4) {
|
||||||
return "i486";
|
return "i486";
|
||||||
if (family == 5)
|
}
|
||||||
|
if (family == 5) {
|
||||||
return "i586";
|
return "i586";
|
||||||
|
}
|
||||||
return "i686";
|
return "i686";
|
||||||
#else
|
#else
|
||||||
/* default is #define-d in each arch/ subdir */
|
/* default is #define-d in each arch/ subdir */
|
||||||
|
|
|
@ -312,6 +312,7 @@ static void set_idt(int n, unsigned int dpl)
|
||||||
|
|
||||||
void cpu_loop(CPUX86State *env)
|
void cpu_loop(CPUX86State *env)
|
||||||
{
|
{
|
||||||
|
CPUState *cs = CPU(x86_env_get_cpu(env));
|
||||||
int trapnr;
|
int trapnr;
|
||||||
abi_ulong pc;
|
abi_ulong pc;
|
||||||
target_siginfo_t info;
|
target_siginfo_t info;
|
||||||
|
@ -443,7 +444,7 @@ void cpu_loop(CPUX86State *env)
|
||||||
{
|
{
|
||||||
int sig;
|
int sig;
|
||||||
|
|
||||||
sig = gdb_handlesig (env, TARGET_SIGTRAP);
|
sig = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||||
if (sig)
|
if (sig)
|
||||||
{
|
{
|
||||||
info.si_signo = sig;
|
info.si_signo = sig;
|
||||||
|
@ -875,7 +876,7 @@ void cpu_loop(CPUARMState *env)
|
||||||
{
|
{
|
||||||
int sig;
|
int sig;
|
||||||
|
|
||||||
sig = gdb_handlesig (env, TARGET_SIGTRAP);
|
sig = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||||
if (sig)
|
if (sig)
|
||||||
{
|
{
|
||||||
info.si_signo = sig;
|
info.si_signo = sig;
|
||||||
|
@ -966,7 +967,7 @@ void cpu_loop(CPUUniCore32State *env)
|
||||||
{
|
{
|
||||||
int sig;
|
int sig;
|
||||||
|
|
||||||
sig = gdb_handlesig(env, TARGET_SIGTRAP);
|
sig = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||||
if (sig) {
|
if (sig) {
|
||||||
info.si_signo = sig;
|
info.si_signo = sig;
|
||||||
info.si_errno = 0;
|
info.si_errno = 0;
|
||||||
|
@ -1233,7 +1234,7 @@ void cpu_loop (CPUSPARCState *env)
|
||||||
{
|
{
|
||||||
int sig;
|
int sig;
|
||||||
|
|
||||||
sig = gdb_handlesig (env, TARGET_SIGTRAP);
|
sig = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||||
if (sig)
|
if (sig)
|
||||||
{
|
{
|
||||||
info.si_signo = sig;
|
info.si_signo = sig;
|
||||||
|
@ -1764,7 +1765,7 @@ void cpu_loop(CPUPPCState *env)
|
||||||
{
|
{
|
||||||
int sig;
|
int sig;
|
||||||
|
|
||||||
sig = gdb_handlesig(env, TARGET_SIGTRAP);
|
sig = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||||
if (sig) {
|
if (sig) {
|
||||||
info.si_signo = sig;
|
info.si_signo = sig;
|
||||||
info.si_errno = 0;
|
info.si_errno = 0;
|
||||||
|
@ -2315,7 +2316,7 @@ done_syscall:
|
||||||
{
|
{
|
||||||
int sig;
|
int sig;
|
||||||
|
|
||||||
sig = gdb_handlesig (env, TARGET_SIGTRAP);
|
sig = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||||
if (sig)
|
if (sig)
|
||||||
{
|
{
|
||||||
info.si_signo = sig;
|
info.si_signo = sig;
|
||||||
|
@ -2475,7 +2476,7 @@ void cpu_loop(CPUOpenRISCState *env)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (gdbsig) {
|
if (gdbsig) {
|
||||||
gdb_handlesig(env, gdbsig);
|
gdb_handlesig(cs, gdbsig);
|
||||||
if (gdbsig != TARGET_SIGTRAP) {
|
if (gdbsig != TARGET_SIGTRAP) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -2518,7 +2519,7 @@ void cpu_loop(CPUSH4State *env)
|
||||||
{
|
{
|
||||||
int sig;
|
int sig;
|
||||||
|
|
||||||
sig = gdb_handlesig (env, TARGET_SIGTRAP);
|
sig = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||||
if (sig)
|
if (sig)
|
||||||
{
|
{
|
||||||
info.si_signo = sig;
|
info.si_signo = sig;
|
||||||
|
@ -2586,7 +2587,7 @@ void cpu_loop(CPUCRISState *env)
|
||||||
{
|
{
|
||||||
int sig;
|
int sig;
|
||||||
|
|
||||||
sig = gdb_handlesig (env, TARGET_SIGTRAP);
|
sig = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||||
if (sig)
|
if (sig)
|
||||||
{
|
{
|
||||||
info.si_signo = sig;
|
info.si_signo = sig;
|
||||||
|
@ -2686,7 +2687,7 @@ void cpu_loop(CPUMBState *env)
|
||||||
{
|
{
|
||||||
int sig;
|
int sig;
|
||||||
|
|
||||||
sig = gdb_handlesig (env, TARGET_SIGTRAP);
|
sig = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||||
if (sig)
|
if (sig)
|
||||||
{
|
{
|
||||||
info.si_signo = sig;
|
info.si_signo = sig;
|
||||||
|
@ -2779,7 +2780,7 @@ void cpu_loop(CPUM68KState *env)
|
||||||
{
|
{
|
||||||
int sig;
|
int sig;
|
||||||
|
|
||||||
sig = gdb_handlesig (env, TARGET_SIGTRAP);
|
sig = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||||
if (sig)
|
if (sig)
|
||||||
{
|
{
|
||||||
info.si_signo = sig;
|
info.si_signo = sig;
|
||||||
|
@ -3006,7 +3007,7 @@ void cpu_loop(CPUAlphaState *env)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EXCP_DEBUG:
|
case EXCP_DEBUG:
|
||||||
info.si_signo = gdb_handlesig (env, TARGET_SIGTRAP);
|
info.si_signo = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||||
if (info.si_signo) {
|
if (info.si_signo) {
|
||||||
env->lock_addr = -1;
|
env->lock_addr = -1;
|
||||||
info.si_errno = 0;
|
info.si_errno = 0;
|
||||||
|
@ -3059,7 +3060,7 @@ void cpu_loop(CPUS390XState *env)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EXCP_DEBUG:
|
case EXCP_DEBUG:
|
||||||
sig = gdb_handlesig(env, TARGET_SIGTRAP);
|
sig = gdb_handlesig(cs, TARGET_SIGTRAP);
|
||||||
if (sig) {
|
if (sig) {
|
||||||
n = TARGET_TRAP_BRKPT;
|
n = TARGET_TRAP_BRKPT;
|
||||||
goto do_signal_pc;
|
goto do_signal_pc;
|
||||||
|
@ -3541,6 +3542,7 @@ int main(int argc, char **argv, char **envp)
|
||||||
struct linux_binprm bprm;
|
struct linux_binprm bprm;
|
||||||
TaskState *ts;
|
TaskState *ts;
|
||||||
CPUArchState *env;
|
CPUArchState *env;
|
||||||
|
CPUState *cpu;
|
||||||
int optind;
|
int optind;
|
||||||
char **target_environ, **wrk;
|
char **target_environ, **wrk;
|
||||||
char **target_argv;
|
char **target_argv;
|
||||||
|
@ -3637,11 +3639,12 @@ int main(int argc, char **argv, char **envp)
|
||||||
fprintf(stderr, "Unable to find CPU definition\n");
|
fprintf(stderr, "Unable to find CPU definition\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
cpu = ENV_GET_CPU(env);
|
||||||
#if defined(TARGET_SPARC) || defined(TARGET_PPC)
|
#if defined(TARGET_SPARC) || defined(TARGET_PPC)
|
||||||
cpu_reset(ENV_GET_CPU(env));
|
cpu_reset(cpu);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
thread_cpu = ENV_GET_CPU(env);
|
thread_cpu = cpu;
|
||||||
|
|
||||||
if (getenv("QEMU_STRACE")) {
|
if (getenv("QEMU_STRACE")) {
|
||||||
do_strace = 1;
|
do_strace = 1;
|
||||||
|
@ -4076,7 +4079,7 @@ int main(int argc, char **argv, char **envp)
|
||||||
gdbstub_port);
|
gdbstub_port);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
gdb_handlesig(env, 0);
|
gdb_handlesig(cpu, 0);
|
||||||
}
|
}
|
||||||
cpu_loop(env);
|
cpu_loop(env);
|
||||||
/* never exits */
|
/* never exits */
|
||||||
|
|
|
@ -5386,6 +5386,7 @@ long do_rt_sigreturn(CPUArchState *env)
|
||||||
|
|
||||||
void process_pending_signals(CPUArchState *cpu_env)
|
void process_pending_signals(CPUArchState *cpu_env)
|
||||||
{
|
{
|
||||||
|
CPUState *cpu = ENV_GET_CPU(cpu_env);
|
||||||
int sig;
|
int sig;
|
||||||
abi_ulong handler;
|
abi_ulong handler;
|
||||||
sigset_t set, old_set;
|
sigset_t set, old_set;
|
||||||
|
@ -5419,7 +5420,7 @@ void process_pending_signals(CPUArchState *cpu_env)
|
||||||
if (!k->first)
|
if (!k->first)
|
||||||
k->pending = 0;
|
k->pending = 0;
|
||||||
|
|
||||||
sig = gdb_handlesig (cpu_env, sig);
|
sig = gdb_handlesig(cpu, sig);
|
||||||
if (!sig) {
|
if (!sig) {
|
||||||
sa = NULL;
|
sa = NULL;
|
||||||
handler = TARGET_SIG_IGN;
|
handler = TARGET_SIG_IGN;
|
||||||
|
|
|
@ -1164,7 +1164,7 @@ static void memory_dump(Monitor *mon, int count, int format, int wsize,
|
||||||
cpu_physical_memory_read(addr, buf, l);
|
cpu_physical_memory_read(addr, buf, l);
|
||||||
} else {
|
} else {
|
||||||
env = mon_get_cpu();
|
env = mon_get_cpu();
|
||||||
if (cpu_memory_rw_debug(env, addr, buf, l, 0) < 0) {
|
if (cpu_memory_rw_debug(ENV_GET_CPU(env), addr, buf, l, 0) < 0) {
|
||||||
monitor_printf(mon, " Cannot access memory\n");
|
monitor_printf(mon, " Cannot access memory\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,5 +81,6 @@ extern const struct VMStateDescription vmstate_alpha_cpu;
|
||||||
void alpha_cpu_do_interrupt(CPUState *cpu);
|
void alpha_cpu_do_interrupt(CPUState *cpu);
|
||||||
void alpha_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
|
void alpha_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
|
||||||
int flags);
|
int flags);
|
||||||
|
hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,6 +24,13 @@
|
||||||
#include "migration/vmstate.h"
|
#include "migration/vmstate.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void alpha_cpu_set_pc(CPUState *cs, vaddr value)
|
||||||
|
{
|
||||||
|
AlphaCPU *cpu = ALPHA_CPU(cs);
|
||||||
|
|
||||||
|
cpu->env.pc = value;
|
||||||
|
}
|
||||||
|
|
||||||
static void alpha_cpu_realizefn(DeviceState *dev, Error **errp)
|
static void alpha_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
AlphaCPUClass *acc = ALPHA_CPU_GET_CLASS(dev);
|
AlphaCPUClass *acc = ALPHA_CPU_GET_CLASS(dev);
|
||||||
|
@ -263,8 +270,12 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
|
||||||
cc->class_by_name = alpha_cpu_class_by_name;
|
cc->class_by_name = alpha_cpu_class_by_name;
|
||||||
cc->do_interrupt = alpha_cpu_do_interrupt;
|
cc->do_interrupt = alpha_cpu_do_interrupt;
|
||||||
cc->dump_state = alpha_cpu_dump_state;
|
cc->dump_state = alpha_cpu_dump_state;
|
||||||
cpu_class_set_do_unassigned_access(cc, alpha_cpu_unassigned_access);
|
cc->set_pc = alpha_cpu_set_pc;
|
||||||
device_class_set_vmsd(dc, &vmstate_alpha_cpu);
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
cc->do_unassigned_access = alpha_cpu_unassigned_access;
|
||||||
|
cc->get_phys_page_debug = alpha_cpu_get_phys_page_debug;
|
||||||
|
dc->vmsd = &vmstate_alpha_cpu;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo alpha_cpu_type_info = {
|
static const TypeInfo alpha_cpu_type_info = {
|
||||||
|
|
|
@ -515,9 +515,4 @@ static inline bool cpu_has_work(CPUState *cpu)
|
||||||
|
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUAlphaState *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->pc = tb->pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !defined (__CPU_ALPHA_H__) */
|
#endif /* !defined (__CPU_ALPHA_H__) */
|
||||||
|
|
|
@ -315,12 +315,13 @@ static int get_physical_address(CPUAlphaState *env, target_ulong addr,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
hwaddr cpu_get_phys_page_debug(CPUAlphaState *env, target_ulong addr)
|
hwaddr alpha_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||||
{
|
{
|
||||||
|
AlphaCPU *cpu = ALPHA_CPU(cs);
|
||||||
target_ulong phys;
|
target_ulong phys;
|
||||||
int prot, fail;
|
int prot, fail;
|
||||||
|
|
||||||
fail = get_physical_address(env, addr, 0, 0, &phys, &prot);
|
fail = get_physical_address(&cpu->env, addr, 0, 0, &phys, &prot);
|
||||||
return (fail >= 0 ? -1 : phys);
|
return (fail >= 0 ? -1 : phys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
typedef struct DisasContext DisasContext;
|
typedef struct DisasContext DisasContext;
|
||||||
struct DisasContext {
|
struct DisasContext {
|
||||||
struct TranslationBlock *tb;
|
struct TranslationBlock *tb;
|
||||||
CPUAlphaState *env;
|
|
||||||
uint64_t pc;
|
uint64_t pc;
|
||||||
int mem_idx;
|
int mem_idx;
|
||||||
|
|
||||||
|
@ -46,6 +45,11 @@ struct DisasContext {
|
||||||
int tb_rm;
|
int tb_rm;
|
||||||
/* Current flush-to-zero setting for this TB. */
|
/* Current flush-to-zero setting for this TB. */
|
||||||
int tb_ftz;
|
int tb_ftz;
|
||||||
|
|
||||||
|
/* implver value for this CPU. */
|
||||||
|
int implver;
|
||||||
|
|
||||||
|
bool singlestep_enabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Return values from translate_one, indicating the state of the TB.
|
/* Return values from translate_one, indicating the state of the TB.
|
||||||
|
@ -380,7 +384,7 @@ static int use_goto_tb(DisasContext *ctx, uint64_t dest)
|
||||||
/* Check for the dest on the same page as the start of the TB. We
|
/* Check for the dest on the same page as the start of the TB. We
|
||||||
also want to suppress goto_tb in the case of single-steping and IO. */
|
also want to suppress goto_tb in the case of single-steping and IO. */
|
||||||
return (((ctx->tb->pc ^ dest) & TARGET_PAGE_MASK) == 0
|
return (((ctx->tb->pc ^ dest) & TARGET_PAGE_MASK) == 0
|
||||||
&& !ctx->env->singlestep_enabled
|
&& !ctx->singlestep_enabled
|
||||||
&& !(ctx->tb->cflags & CF_LAST_IO));
|
&& !(ctx->tb->cflags & CF_LAST_IO));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2248,8 +2252,9 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
|
||||||
break;
|
break;
|
||||||
case 0x6C:
|
case 0x6C:
|
||||||
/* IMPLVER */
|
/* IMPLVER */
|
||||||
if (rc != 31)
|
if (rc != 31) {
|
||||||
tcg_gen_movi_i64(cpu_ir[rc], ctx->env->implver);
|
tcg_gen_movi_i64(cpu_ir[rc], ctx->implver);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
goto invalid_opc;
|
goto invalid_opc;
|
||||||
|
@ -3383,6 +3388,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
|
||||||
TranslationBlock *tb,
|
TranslationBlock *tb,
|
||||||
bool search_pc)
|
bool search_pc)
|
||||||
{
|
{
|
||||||
|
CPUState *cs = CPU(cpu);
|
||||||
CPUAlphaState *env = &cpu->env;
|
CPUAlphaState *env = &cpu->env;
|
||||||
DisasContext ctx, *ctxp = &ctx;
|
DisasContext ctx, *ctxp = &ctx;
|
||||||
target_ulong pc_start;
|
target_ulong pc_start;
|
||||||
|
@ -3398,9 +3404,10 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
|
||||||
gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
|
gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
|
||||||
|
|
||||||
ctx.tb = tb;
|
ctx.tb = tb;
|
||||||
ctx.env = env;
|
|
||||||
ctx.pc = pc_start;
|
ctx.pc = pc_start;
|
||||||
ctx.mem_idx = cpu_mmu_index(env);
|
ctx.mem_idx = cpu_mmu_index(env);
|
||||||
|
ctx.implver = env->implver;
|
||||||
|
ctx.singlestep_enabled = cs->singlestep_enabled;
|
||||||
|
|
||||||
/* ??? Every TB begins with unset rounding mode, to be initialized on
|
/* ??? Every TB begins with unset rounding mode, to be initialized on
|
||||||
the first fp insn of the TB. Alternately we could define a proper
|
the first fp insn of the TB. Alternately we could define a proper
|
||||||
|
@ -3457,7 +3464,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
|
||||||
|| tcg_ctx.gen_opc_ptr >= gen_opc_end
|
|| tcg_ctx.gen_opc_ptr >= gen_opc_end
|
||||||
|| num_insns >= max_insns
|
|| num_insns >= max_insns
|
||||||
|| singlestep
|
|| singlestep
|
||||||
|| env->singlestep_enabled)) {
|
|| ctx.singlestep_enabled)) {
|
||||||
ret = EXIT_PC_STALE;
|
ret = EXIT_PC_STALE;
|
||||||
}
|
}
|
||||||
} while (ret == NO_EXIT);
|
} while (ret == NO_EXIT);
|
||||||
|
@ -3474,7 +3481,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
|
||||||
tcg_gen_movi_i64(cpu_pc, ctx.pc);
|
tcg_gen_movi_i64(cpu_pc, ctx.pc);
|
||||||
/* FALLTHRU */
|
/* FALLTHRU */
|
||||||
case EXIT_PC_UPDATED:
|
case EXIT_PC_UPDATED:
|
||||||
if (env->singlestep_enabled) {
|
if (ctx.singlestep_enabled) {
|
||||||
gen_excp_1(EXCP_DEBUG, 0);
|
gen_excp_1(EXCP_DEBUG, 0);
|
||||||
} else {
|
} else {
|
||||||
tcg_gen_exit_tb(0);
|
tcg_gen_exit_tb(0);
|
||||||
|
|
|
@ -122,8 +122,10 @@ static target_ulong arm_semi_syscall_len;
|
||||||
static target_ulong syscall_err;
|
static target_ulong syscall_err;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void arm_semi_cb(CPUARMState *env, target_ulong ret, target_ulong err)
|
static void arm_semi_cb(CPUState *cs, target_ulong ret, target_ulong err)
|
||||||
{
|
{
|
||||||
|
ARMCPU *cpu = ARM_CPU(cs);
|
||||||
|
CPUARMState *env = &cpu->env;
|
||||||
#ifdef CONFIG_USER_ONLY
|
#ifdef CONFIG_USER_ONLY
|
||||||
TaskState *ts = env->opaque;
|
TaskState *ts = env->opaque;
|
||||||
#endif
|
#endif
|
||||||
|
@ -152,12 +154,14 @@ static void arm_semi_cb(CPUARMState *env, target_ulong ret, target_ulong err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void arm_semi_flen_cb(CPUARMState *env, target_ulong ret, target_ulong err)
|
static void arm_semi_flen_cb(CPUState *cs, target_ulong ret, target_ulong err)
|
||||||
{
|
{
|
||||||
|
ARMCPU *cpu = ARM_CPU(cs);
|
||||||
|
CPUARMState *env = &cpu->env;
|
||||||
/* The size is always stored in big-endian order, extract
|
/* The size is always stored in big-endian order, extract
|
||||||
the value. We assume the size always fit in 32 bits. */
|
the value. We assume the size always fit in 32 bits. */
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
cpu_memory_rw_debug(env, env->regs[13]-64+32, (uint8_t *)&size, 4, 0);
|
cpu_memory_rw_debug(cs, env->regs[13]-64+32, (uint8_t *)&size, 4, 0);
|
||||||
env->regs[0] = be32_to_cpu(size);
|
env->regs[0] = be32_to_cpu(size);
|
||||||
#ifdef CONFIG_USER_ONLY
|
#ifdef CONFIG_USER_ONLY
|
||||||
((TaskState *)env->opaque)->swi_errno = err;
|
((TaskState *)env->opaque)->swi_errno = err;
|
||||||
|
|
|
@ -147,4 +147,6 @@ void arm_v7m_cpu_do_interrupt(CPUState *cpu);
|
||||||
void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
|
void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
|
||||||
int flags);
|
int flags);
|
||||||
|
|
||||||
|
hwaddr arm_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -25,6 +25,13 @@
|
||||||
#endif
|
#endif
|
||||||
#include "sysemu/sysemu.h"
|
#include "sysemu/sysemu.h"
|
||||||
|
|
||||||
|
static void arm_cpu_set_pc(CPUState *cs, vaddr value)
|
||||||
|
{
|
||||||
|
ARMCPU *cpu = ARM_CPU(cs);
|
||||||
|
|
||||||
|
cpu->env.regs[15] = value;
|
||||||
|
}
|
||||||
|
|
||||||
static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
|
static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
|
||||||
{
|
{
|
||||||
/* Reset a single ARMCPRegInfo register */
|
/* Reset a single ARMCPRegInfo register */
|
||||||
|
@ -816,7 +823,11 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
|
||||||
cc->class_by_name = arm_cpu_class_by_name;
|
cc->class_by_name = arm_cpu_class_by_name;
|
||||||
cc->do_interrupt = arm_cpu_do_interrupt;
|
cc->do_interrupt = arm_cpu_do_interrupt;
|
||||||
cc->dump_state = arm_cpu_dump_state;
|
cc->dump_state = arm_cpu_dump_state;
|
||||||
cpu_class_set_vmsd(cc, &vmstate_arm_cpu);
|
cc->set_pc = arm_cpu_set_pc;
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
cc->get_phys_page_debug = arm_cpu_get_phys_page_debug;
|
||||||
|
cc->vmsd = &vmstate_arm_cpu;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cpu_register(const ARMCPUInfo *info)
|
static void cpu_register(const ARMCPUInfo *info)
|
||||||
|
|
|
@ -797,11 +797,6 @@ static inline bool cpu_has_work(CPUState *cpu)
|
||||||
|
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUARMState *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->regs[15] = tb->pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load an instruction and return it in the standard little-endian order */
|
/* Load an instruction and return it in the standard little-endian order */
|
||||||
static inline uint32_t arm_ldl_code(CPUARMState *env, uint32_t addr,
|
static inline uint32_t arm_ldl_code(CPUARMState *env, uint32_t addr,
|
||||||
bool do_swap)
|
bool do_swap)
|
||||||
|
|
|
@ -1513,16 +1513,17 @@ ARMCPU *cpu_arm_init(const char *cpu_model)
|
||||||
|
|
||||||
void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
|
void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
|
||||||
{
|
{
|
||||||
|
CPUState *cs = CPU(cpu);
|
||||||
CPUARMState *env = &cpu->env;
|
CPUARMState *env = &cpu->env;
|
||||||
|
|
||||||
if (arm_feature(env, ARM_FEATURE_NEON)) {
|
if (arm_feature(env, ARM_FEATURE_NEON)) {
|
||||||
gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg,
|
gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
|
||||||
51, "arm-neon.xml", 0);
|
51, "arm-neon.xml", 0);
|
||||||
} else if (arm_feature(env, ARM_FEATURE_VFP3)) {
|
} else if (arm_feature(env, ARM_FEATURE_VFP3)) {
|
||||||
gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg,
|
gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
|
||||||
35, "arm-vfp3.xml", 0);
|
35, "arm-vfp3.xml", 0);
|
||||||
} else if (arm_feature(env, ARM_FEATURE_VFP)) {
|
} else if (arm_feature(env, ARM_FEATURE_VFP)) {
|
||||||
gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg,
|
gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg,
|
||||||
19, "arm-vfp.xml", 0);
|
19, "arm-vfp.xml", 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2762,17 +2763,19 @@ int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
hwaddr cpu_get_phys_page_debug(CPUARMState *env, target_ulong addr)
|
hwaddr arm_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||||
{
|
{
|
||||||
|
ARMCPU *cpu = ARM_CPU(cs);
|
||||||
hwaddr phys_addr;
|
hwaddr phys_addr;
|
||||||
target_ulong page_size;
|
target_ulong page_size;
|
||||||
int prot;
|
int prot;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = get_phys_addr(env, addr, 0, 0, &phys_addr, &prot, &page_size);
|
ret = get_phys_addr(&cpu->env, addr, 0, 0, &phys_addr, &prot, &page_size);
|
||||||
|
|
||||||
if (ret != 0)
|
if (ret != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return phys_addr;
|
return phys_addr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9911,6 +9911,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
|
||||||
TranslationBlock *tb,
|
TranslationBlock *tb,
|
||||||
bool search_pc)
|
bool search_pc)
|
||||||
{
|
{
|
||||||
|
CPUState *cs = CPU(cpu);
|
||||||
CPUARMState *env = &cpu->env;
|
CPUARMState *env = &cpu->env;
|
||||||
DisasContext dc1, *dc = &dc1;
|
DisasContext dc1, *dc = &dc1;
|
||||||
CPUBreakpoint *bp;
|
CPUBreakpoint *bp;
|
||||||
|
@ -9930,7 +9931,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
|
||||||
|
|
||||||
dc->is_jmp = DISAS_NEXT;
|
dc->is_jmp = DISAS_NEXT;
|
||||||
dc->pc = pc_start;
|
dc->pc = pc_start;
|
||||||
dc->singlestep_enabled = env->singlestep_enabled;
|
dc->singlestep_enabled = cs->singlestep_enabled;
|
||||||
dc->condjmp = 0;
|
dc->condjmp = 0;
|
||||||
dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
|
dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
|
||||||
dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
|
dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
|
||||||
|
@ -10080,7 +10081,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
|
||||||
* ensures prefetch aborts occur at the right place. */
|
* ensures prefetch aborts occur at the right place. */
|
||||||
num_insns ++;
|
num_insns ++;
|
||||||
} while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
|
} while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
|
||||||
!env->singlestep_enabled &&
|
!cs->singlestep_enabled &&
|
||||||
!singlestep &&
|
!singlestep &&
|
||||||
dc->pc < next_page_start &&
|
dc->pc < next_page_start &&
|
||||||
num_insns < max_insns);
|
num_insns < max_insns);
|
||||||
|
@ -10097,7 +10098,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu,
|
||||||
/* At this stage dc->condjmp will only be set when the skipped
|
/* At this stage dc->condjmp will only be set when the skipped
|
||||||
instruction was a conditional branch or trap, and the PC has
|
instruction was a conditional branch or trap, and the PC has
|
||||||
already been written. */
|
already been written. */
|
||||||
if (unlikely(env->singlestep_enabled)) {
|
if (unlikely(cs->singlestep_enabled)) {
|
||||||
/* Make sure the pc is updated, and raise a debug exception. */
|
/* Make sure the pc is updated, and raise a debug exception. */
|
||||||
if (dc->condjmp) {
|
if (dc->condjmp) {
|
||||||
gen_set_condexec(dc);
|
gen_set_condexec(dc);
|
||||||
|
|
|
@ -79,4 +79,6 @@ void crisv10_cpu_do_interrupt(CPUState *cpu);
|
||||||
void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
|
void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
|
||||||
int flags);
|
int flags);
|
||||||
|
|
||||||
|
hwaddr cris_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -26,6 +26,13 @@
|
||||||
#include "mmu.h"
|
#include "mmu.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void cris_cpu_set_pc(CPUState *cs, vaddr value)
|
||||||
|
{
|
||||||
|
CRISCPU *cpu = CRIS_CPU(cs);
|
||||||
|
|
||||||
|
cpu->env.pc = value;
|
||||||
|
}
|
||||||
|
|
||||||
/* CPUClass::reset() */
|
/* CPUClass::reset() */
|
||||||
static void cris_cpu_reset(CPUState *s)
|
static void cris_cpu_reset(CPUState *s)
|
||||||
{
|
{
|
||||||
|
@ -247,6 +254,10 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
|
||||||
cc->class_by_name = cris_cpu_class_by_name;
|
cc->class_by_name = cris_cpu_class_by_name;
|
||||||
cc->do_interrupt = cris_cpu_do_interrupt;
|
cc->do_interrupt = cris_cpu_do_interrupt;
|
||||||
cc->dump_state = cris_cpu_dump_state;
|
cc->dump_state = cris_cpu_dump_state;
|
||||||
|
cc->set_pc = cris_cpu_set_pc;
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
cc->get_phys_page_debug = cris_cpu_get_phys_page_debug;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo cris_cpu_type_info = {
|
static const TypeInfo cris_cpu_type_info = {
|
||||||
|
|
|
@ -279,8 +279,4 @@ static inline bool cpu_has_work(CPUState *cpu)
|
||||||
|
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUCRISState *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->pc = tb->pc;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -255,16 +255,17 @@ void cris_cpu_do_interrupt(CPUState *cs)
|
||||||
env->pregs[PR_ERP]);
|
env->pregs[PR_ERP]);
|
||||||
}
|
}
|
||||||
|
|
||||||
hwaddr cpu_get_phys_page_debug(CPUCRISState * env, target_ulong addr)
|
hwaddr cris_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||||
{
|
{
|
||||||
|
CRISCPU *cpu = CRIS_CPU(cs);
|
||||||
uint32_t phy = addr;
|
uint32_t phy = addr;
|
||||||
struct cris_mmu_result res;
|
struct cris_mmu_result res;
|
||||||
int miss;
|
int miss;
|
||||||
|
|
||||||
miss = cris_mmu_translate(&res, env, addr, 0, 0, 1);
|
miss = cris_mmu_translate(&res, &cpu->env, addr, 0, 0, 1);
|
||||||
/* If D TLB misses, try I TLB. */
|
/* If D TLB misses, try I TLB. */
|
||||||
if (miss) {
|
if (miss) {
|
||||||
miss = cris_mmu_translate(&res, env, addr, 2, 0, 1);
|
miss = cris_mmu_translate(&res, &cpu->env, addr, 2, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!miss) {
|
if (!miss) {
|
||||||
|
|
|
@ -3165,6 +3165,7 @@ static inline void
|
||||||
gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb,
|
gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb,
|
||||||
bool search_pc)
|
bool search_pc)
|
||||||
{
|
{
|
||||||
|
CPUState *cs = CPU(cpu);
|
||||||
CPUCRISState *env = &cpu->env;
|
CPUCRISState *env = &cpu->env;
|
||||||
uint16_t *gen_opc_end;
|
uint16_t *gen_opc_end;
|
||||||
uint32_t pc_start;
|
uint32_t pc_start;
|
||||||
|
@ -3197,7 +3198,7 @@ gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb,
|
||||||
dc->is_jmp = DISAS_NEXT;
|
dc->is_jmp = DISAS_NEXT;
|
||||||
dc->ppc = pc_start;
|
dc->ppc = pc_start;
|
||||||
dc->pc = pc_start;
|
dc->pc = pc_start;
|
||||||
dc->singlestep_enabled = env->singlestep_enabled;
|
dc->singlestep_enabled = cs->singlestep_enabled;
|
||||||
dc->flags_uptodate = 1;
|
dc->flags_uptodate = 1;
|
||||||
dc->flagx_known = 1;
|
dc->flagx_known = 1;
|
||||||
dc->flags_x = tb->flags & X_FLAG;
|
dc->flags_x = tb->flags & X_FLAG;
|
||||||
|
@ -3337,7 +3338,7 @@ gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb,
|
||||||
|
|
||||||
/* If we are rexecuting a branch due to exceptions on
|
/* If we are rexecuting a branch due to exceptions on
|
||||||
delay slots dont break. */
|
delay slots dont break. */
|
||||||
if (!(tb->pc & 1) && env->singlestep_enabled) {
|
if (!(tb->pc & 1) && cs->singlestep_enabled) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (!dc->is_jmp && !dc->cpustate_changed
|
} while (!dc->is_jmp && !dc->cpustate_changed
|
||||||
|
@ -3370,7 +3371,7 @@ gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb,
|
||||||
|
|
||||||
cris_evaluate_flags(dc);
|
cris_evaluate_flags(dc);
|
||||||
|
|
||||||
if (unlikely(env->singlestep_enabled)) {
|
if (unlikely(cs->singlestep_enabled)) {
|
||||||
if (dc->is_jmp == DISAS_NEXT) {
|
if (dc->is_jmp == DISAS_NEXT) {
|
||||||
tcg_gen_movi_tl(env_pc, npc);
|
tcg_gen_movi_tl(env_pc, npc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,4 +104,6 @@ void x86_cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
|
||||||
void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
|
void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
|
||||||
int flags);
|
int flags);
|
||||||
|
|
||||||
|
hwaddr x86_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2506,6 +2506,20 @@ static bool x86_cpu_get_paging_enabled(const CPUState *cs)
|
||||||
return cpu->env.cr[0] & CR0_PG_MASK;
|
return cpu->env.cr[0] & CR0_PG_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void x86_cpu_set_pc(CPUState *cs, vaddr value)
|
||||||
|
{
|
||||||
|
X86CPU *cpu = X86_CPU(cs);
|
||||||
|
|
||||||
|
cpu->env.eip = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void x86_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
|
||||||
|
{
|
||||||
|
X86CPU *cpu = X86_CPU(cs);
|
||||||
|
|
||||||
|
cpu->env.eip = tb->pc - tb->cs_base;
|
||||||
|
}
|
||||||
|
|
||||||
static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
|
static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
|
||||||
{
|
{
|
||||||
X86CPUClass *xcc = X86_CPU_CLASS(oc);
|
X86CPUClass *xcc = X86_CPU_CLASS(oc);
|
||||||
|
@ -2522,16 +2536,19 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
|
||||||
|
|
||||||
cc->do_interrupt = x86_cpu_do_interrupt;
|
cc->do_interrupt = x86_cpu_do_interrupt;
|
||||||
cc->dump_state = x86_cpu_dump_state;
|
cc->dump_state = x86_cpu_dump_state;
|
||||||
|
cc->set_pc = x86_cpu_set_pc;
|
||||||
|
cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
|
||||||
cc->get_arch_id = x86_cpu_get_arch_id;
|
cc->get_arch_id = x86_cpu_get_arch_id;
|
||||||
cc->get_paging_enabled = x86_cpu_get_paging_enabled;
|
cc->get_paging_enabled = x86_cpu_get_paging_enabled;
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
cc->get_memory_mapping = x86_cpu_get_memory_mapping;
|
cc->get_memory_mapping = x86_cpu_get_memory_mapping;
|
||||||
|
cc->get_phys_page_debug = x86_cpu_get_phys_page_debug;
|
||||||
cc->write_elf64_note = x86_cpu_write_elf64_note;
|
cc->write_elf64_note = x86_cpu_write_elf64_note;
|
||||||
cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote;
|
cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote;
|
||||||
cc->write_elf32_note = x86_cpu_write_elf32_note;
|
cc->write_elf32_note = x86_cpu_write_elf32_note;
|
||||||
cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
|
cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
|
||||||
|
cc->vmsd = &vmstate_x86_cpu;
|
||||||
#endif
|
#endif
|
||||||
cpu_class_set_vmsd(cc, &vmstate_x86_cpu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo x86_cpu_type_info = {
|
static const TypeInfo x86_cpu_type_info = {
|
||||||
|
|
|
@ -1148,11 +1148,6 @@ static inline bool cpu_has_work(CPUState *cs)
|
||||||
|
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUX86State *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->eip = tb->pc - tb->cs_base;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void cpu_get_tb_cpu_state(CPUX86State *env, target_ulong *pc,
|
static inline void cpu_get_tb_cpu_state(CPUX86State *env, target_ulong *pc,
|
||||||
target_ulong *cs_base, int *flags)
|
target_ulong *cs_base, int *flags)
|
||||||
{
|
{
|
||||||
|
|
|
@ -363,7 +363,7 @@ void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
|
||||||
|
|
||||||
cpu_fprintf(f, "Code=");
|
cpu_fprintf(f, "Code=");
|
||||||
for (i = 0; i < DUMP_CODE_BYTES_TOTAL; i++) {
|
for (i = 0; i < DUMP_CODE_BYTES_TOTAL; i++) {
|
||||||
if (cpu_memory_rw_debug(env, base - offs + i, &code, 1, 0) == 0) {
|
if (cpu_memory_rw_debug(cs, base - offs + i, &code, 1, 0) == 0) {
|
||||||
snprintf(codestr, sizeof(codestr), "%02x", code);
|
snprintf(codestr, sizeof(codestr), "%02x", code);
|
||||||
} else {
|
} else {
|
||||||
snprintf(codestr, sizeof(codestr), "??");
|
snprintf(codestr, sizeof(codestr), "??");
|
||||||
|
@ -884,8 +884,10 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
hwaddr cpu_get_phys_page_debug(CPUX86State *env, target_ulong addr)
|
hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||||
{
|
{
|
||||||
|
X86CPU *cpu = X86_CPU(cs);
|
||||||
|
CPUX86State *env = &cpu->env;
|
||||||
target_ulong pde_addr, pte_addr;
|
target_ulong pde_addr, pte_addr;
|
||||||
uint64_t pte;
|
uint64_t pte;
|
||||||
hwaddr paddr;
|
hwaddr paddr;
|
||||||
|
@ -1258,6 +1260,8 @@ int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
|
||||||
target_ulong *base, unsigned int *limit,
|
target_ulong *base, unsigned int *limit,
|
||||||
unsigned int *flags)
|
unsigned int *flags)
|
||||||
{
|
{
|
||||||
|
X86CPU *cpu = x86_env_get_cpu(env);
|
||||||
|
CPUState *cs = CPU(cpu);
|
||||||
SegmentCache *dt;
|
SegmentCache *dt;
|
||||||
target_ulong ptr;
|
target_ulong ptr;
|
||||||
uint32_t e1, e2;
|
uint32_t e1, e2;
|
||||||
|
@ -1270,8 +1274,8 @@ int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
|
||||||
index = selector & ~7;
|
index = selector & ~7;
|
||||||
ptr = dt->base + index;
|
ptr = dt->base + index;
|
||||||
if ((index + 7) > dt->limit
|
if ((index + 7) > dt->limit
|
||||||
|| cpu_memory_rw_debug(env, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
|
|| cpu_memory_rw_debug(cs, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
|
||||||
|| cpu_memory_rw_debug(env, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
|
|| cpu_memory_rw_debug(cs, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
*base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
|
*base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
|
||||||
|
|
|
@ -1594,6 +1594,7 @@ static int kvm_get_vcpu_events(X86CPU *cpu)
|
||||||
|
|
||||||
static int kvm_guest_debug_workarounds(X86CPU *cpu)
|
static int kvm_guest_debug_workarounds(X86CPU *cpu)
|
||||||
{
|
{
|
||||||
|
CPUState *cs = CPU(cpu);
|
||||||
CPUX86State *env = &cpu->env;
|
CPUX86State *env = &cpu->env;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
unsigned long reinject_trap = 0;
|
unsigned long reinject_trap = 0;
|
||||||
|
@ -1616,7 +1617,7 @@ static int kvm_guest_debug_workarounds(X86CPU *cpu)
|
||||||
* reinject them via SET_GUEST_DEBUG.
|
* reinject them via SET_GUEST_DEBUG.
|
||||||
*/
|
*/
|
||||||
if (reinject_trap ||
|
if (reinject_trap ||
|
||||||
(!kvm_has_robust_singlestep() && env->singlestep_enabled)) {
|
(!kvm_has_robust_singlestep() && cs->singlestep_enabled)) {
|
||||||
ret = kvm_update_guest_debug(env, reinject_trap);
|
ret = kvm_update_guest_debug(env, reinject_trap);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1931,25 +1932,23 @@ static int kvm_handle_tpr_access(X86CPU *cpu)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kvm_arch_insert_sw_breakpoint(CPUState *cpu, struct kvm_sw_breakpoint *bp)
|
int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
|
||||||
{
|
{
|
||||||
CPUX86State *env = &X86_CPU(cpu)->env;
|
|
||||||
static const uint8_t int3 = 0xcc;
|
static const uint8_t int3 = 0xcc;
|
||||||
|
|
||||||
if (cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 1, 0) ||
|
if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 1, 0) ||
|
||||||
cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&int3, 1, 1)) {
|
cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&int3, 1, 1)) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kvm_arch_remove_sw_breakpoint(CPUState *cpu, struct kvm_sw_breakpoint *bp)
|
int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
|
||||||
{
|
{
|
||||||
CPUX86State *env = &X86_CPU(cpu)->env;
|
|
||||||
uint8_t int3;
|
uint8_t int3;
|
||||||
|
|
||||||
if (cpu_memory_rw_debug(env, bp->pc, &int3, 1, 0) || int3 != 0xcc ||
|
if (cpu_memory_rw_debug(cs, bp->pc, &int3, 1, 0) || int3 != 0xcc ||
|
||||||
cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 1, 1)) {
|
cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 1, 1)) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2042,13 +2041,14 @@ static CPUWatchpoint hw_watchpoint;
|
||||||
static int kvm_handle_debug(X86CPU *cpu,
|
static int kvm_handle_debug(X86CPU *cpu,
|
||||||
struct kvm_debug_exit_arch *arch_info)
|
struct kvm_debug_exit_arch *arch_info)
|
||||||
{
|
{
|
||||||
|
CPUState *cs = CPU(cpu);
|
||||||
CPUX86State *env = &cpu->env;
|
CPUX86State *env = &cpu->env;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if (arch_info->exception == 1) {
|
if (arch_info->exception == 1) {
|
||||||
if (arch_info->dr6 & (1 << 14)) {
|
if (arch_info->dr6 & (1 << 14)) {
|
||||||
if (env->singlestep_enabled) {
|
if (cs->singlestep_enabled) {
|
||||||
ret = EXCP_DEBUG;
|
ret = EXCP_DEBUG;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -8255,6 +8255,7 @@ static inline void gen_intermediate_code_internal(X86CPU *cpu,
|
||||||
TranslationBlock *tb,
|
TranslationBlock *tb,
|
||||||
bool search_pc)
|
bool search_pc)
|
||||||
{
|
{
|
||||||
|
CPUState *cs = CPU(cpu);
|
||||||
CPUX86State *env = &cpu->env;
|
CPUX86State *env = &cpu->env;
|
||||||
DisasContext dc1, *dc = &dc1;
|
DisasContext dc1, *dc = &dc1;
|
||||||
target_ulong pc_ptr;
|
target_ulong pc_ptr;
|
||||||
|
@ -8281,7 +8282,7 @@ static inline void gen_intermediate_code_internal(X86CPU *cpu,
|
||||||
dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
|
dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
|
||||||
dc->iopl = (flags >> IOPL_SHIFT) & 3;
|
dc->iopl = (flags >> IOPL_SHIFT) & 3;
|
||||||
dc->tf = (flags >> TF_SHIFT) & 1;
|
dc->tf = (flags >> TF_SHIFT) & 1;
|
||||||
dc->singlestep_enabled = env->singlestep_enabled;
|
dc->singlestep_enabled = cs->singlestep_enabled;
|
||||||
dc->cc_op = CC_OP_DYNAMIC;
|
dc->cc_op = CC_OP_DYNAMIC;
|
||||||
dc->cc_op_dirty = false;
|
dc->cc_op_dirty = false;
|
||||||
dc->cs_base = cs_base;
|
dc->cs_base = cs_base;
|
||||||
|
@ -8302,7 +8303,7 @@ static inline void gen_intermediate_code_internal(X86CPU *cpu,
|
||||||
dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
|
dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
|
||||||
#endif
|
#endif
|
||||||
dc->flags = flags;
|
dc->flags = flags;
|
||||||
dc->jmp_opt = !(dc->tf || env->singlestep_enabled ||
|
dc->jmp_opt = !(dc->tf || cs->singlestep_enabled ||
|
||||||
(flags & HF_INHIBIT_IRQ_MASK)
|
(flags & HF_INHIBIT_IRQ_MASK)
|
||||||
#ifndef CONFIG_SOFTMMU
|
#ifndef CONFIG_SOFTMMU
|
||||||
|| (flags & HF_SOFTMMU_MASK)
|
|| (flags & HF_SOFTMMU_MASK)
|
||||||
|
|
|
@ -78,5 +78,6 @@ extern const struct VMStateDescription vmstate_lm32_cpu;
|
||||||
void lm32_cpu_do_interrupt(CPUState *cpu);
|
void lm32_cpu_do_interrupt(CPUState *cpu);
|
||||||
void lm32_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
|
void lm32_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
|
||||||
int flags);
|
int flags);
|
||||||
|
hwaddr lm32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,6 +22,13 @@
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void lm32_cpu_set_pc(CPUState *cs, vaddr value)
|
||||||
|
{
|
||||||
|
LM32CPU *cpu = LM32_CPU(cs);
|
||||||
|
|
||||||
|
cpu->env.pc = value;
|
||||||
|
}
|
||||||
|
|
||||||
/* CPUClass::reset() */
|
/* CPUClass::reset() */
|
||||||
static void lm32_cpu_reset(CPUState *s)
|
static void lm32_cpu_reset(CPUState *s)
|
||||||
{
|
{
|
||||||
|
@ -79,7 +86,11 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
|
||||||
|
|
||||||
cc->do_interrupt = lm32_cpu_do_interrupt;
|
cc->do_interrupt = lm32_cpu_do_interrupt;
|
||||||
cc->dump_state = lm32_cpu_dump_state;
|
cc->dump_state = lm32_cpu_dump_state;
|
||||||
cpu_class_set_vmsd(cc, &vmstate_lm32_cpu);
|
cc->set_pc = lm32_cpu_set_pc;
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
cc->get_phys_page_debug = lm32_cpu_get_phys_page_debug;
|
||||||
|
cc->vmsd = &vmstate_lm32_cpu;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo lm32_cpu_type_info = {
|
static const TypeInfo lm32_cpu_type_info = {
|
||||||
|
|
|
@ -232,9 +232,4 @@ static inline bool cpu_has_work(CPUState *cpu)
|
||||||
|
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPULM32State *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->pc = tb->pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -37,10 +37,12 @@ int cpu_lm32_handle_mmu_fault(CPULM32State *env, target_ulong address, int rw,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
hwaddr cpu_get_phys_page_debug(CPULM32State *env, target_ulong addr)
|
hwaddr lm32_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||||
{
|
{
|
||||||
|
LM32CPU *cpu = LM32_CPU(cs);
|
||||||
|
|
||||||
addr &= TARGET_PAGE_MASK;
|
addr &= TARGET_PAGE_MASK;
|
||||||
if (env->flags & LM32_FLAG_IGNORE_MSB) {
|
if (cpu->env.flags & LM32_FLAG_IGNORE_MSB) {
|
||||||
return addr & 0x7fffffff;
|
return addr & 0x7fffffff;
|
||||||
} else {
|
} else {
|
||||||
return addr;
|
return addr;
|
||||||
|
|
|
@ -1015,6 +1015,7 @@ static inline
|
||||||
void gen_intermediate_code_internal(LM32CPU *cpu,
|
void gen_intermediate_code_internal(LM32CPU *cpu,
|
||||||
TranslationBlock *tb, bool search_pc)
|
TranslationBlock *tb, bool search_pc)
|
||||||
{
|
{
|
||||||
|
CPUState *cs = CPU(cpu);
|
||||||
CPULM32State *env = &cpu->env;
|
CPULM32State *env = &cpu->env;
|
||||||
struct DisasContext ctx, *dc = &ctx;
|
struct DisasContext ctx, *dc = &ctx;
|
||||||
uint16_t *gen_opc_end;
|
uint16_t *gen_opc_end;
|
||||||
|
@ -1032,7 +1033,7 @@ void gen_intermediate_code_internal(LM32CPU *cpu,
|
||||||
|
|
||||||
dc->is_jmp = DISAS_NEXT;
|
dc->is_jmp = DISAS_NEXT;
|
||||||
dc->pc = pc_start;
|
dc->pc = pc_start;
|
||||||
dc->singlestep_enabled = env->singlestep_enabled;
|
dc->singlestep_enabled = cs->singlestep_enabled;
|
||||||
dc->nr_nops = 0;
|
dc->nr_nops = 0;
|
||||||
|
|
||||||
if (pc_start & 3) {
|
if (pc_start & 3) {
|
||||||
|
@ -1077,7 +1078,7 @@ void gen_intermediate_code_internal(LM32CPU *cpu,
|
||||||
|
|
||||||
} while (!dc->is_jmp
|
} while (!dc->is_jmp
|
||||||
&& tcg_ctx.gen_opc_ptr < gen_opc_end
|
&& tcg_ctx.gen_opc_ptr < gen_opc_end
|
||||||
&& !env->singlestep_enabled
|
&& !cs->singlestep_enabled
|
||||||
&& !singlestep
|
&& !singlestep
|
||||||
&& (dc->pc < next_page_start)
|
&& (dc->pc < next_page_start)
|
||||||
&& num_insns < max_insns);
|
&& num_insns < max_insns);
|
||||||
|
@ -1086,7 +1087,7 @@ void gen_intermediate_code_internal(LM32CPU *cpu,
|
||||||
gen_io_end();
|
gen_io_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(env->singlestep_enabled)) {
|
if (unlikely(cs->singlestep_enabled)) {
|
||||||
if (dc->is_jmp == DISAS_NEXT) {
|
if (dc->is_jmp == DISAS_NEXT) {
|
||||||
tcg_gen_movi_tl(cpu_pc, dc->pc);
|
tcg_gen_movi_tl(cpu_pc, dc->pc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,5 +73,6 @@ static inline M68kCPU *m68k_env_get_cpu(CPUM68KState *env)
|
||||||
void m68k_cpu_do_interrupt(CPUState *cpu);
|
void m68k_cpu_do_interrupt(CPUState *cpu);
|
||||||
void m68k_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
|
void m68k_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
|
||||||
int flags);
|
int flags);
|
||||||
|
hwaddr m68k_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,6 +23,13 @@
|
||||||
#include "migration/vmstate.h"
|
#include "migration/vmstate.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void m68k_cpu_set_pc(CPUState *cs, vaddr value)
|
||||||
|
{
|
||||||
|
M68kCPU *cpu = M68K_CPU(cs);
|
||||||
|
|
||||||
|
cpu->env.pc = value;
|
||||||
|
}
|
||||||
|
|
||||||
static void m68k_set_feature(CPUM68KState *env, int feature)
|
static void m68k_set_feature(CPUM68KState *env, int feature)
|
||||||
{
|
{
|
||||||
env->features |= (1u << feature);
|
env->features |= (1u << feature);
|
||||||
|
@ -182,6 +189,10 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
|
||||||
cc->class_by_name = m68k_cpu_class_by_name;
|
cc->class_by_name = m68k_cpu_class_by_name;
|
||||||
cc->do_interrupt = m68k_cpu_do_interrupt;
|
cc->do_interrupt = m68k_cpu_do_interrupt;
|
||||||
cc->dump_state = m68k_cpu_dump_state;
|
cc->dump_state = m68k_cpu_dump_state;
|
||||||
|
cc->set_pc = m68k_cpu_set_pc;
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
cc->get_phys_page_debug = m68k_cpu_get_phys_page_debug;
|
||||||
|
#endif
|
||||||
dc->vmsd = &vmstate_m68k_cpu;
|
dc->vmsd = &vmstate_m68k_cpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -260,9 +260,4 @@ static inline bool cpu_has_work(CPUState *cpu)
|
||||||
|
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUM68KState *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->pc = tb->pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -121,10 +121,11 @@ M68kCPU *cpu_m68k_init(const char *cpu_model)
|
||||||
|
|
||||||
void m68k_cpu_init_gdb(M68kCPU *cpu)
|
void m68k_cpu_init_gdb(M68kCPU *cpu)
|
||||||
{
|
{
|
||||||
|
CPUState *cs = CPU(cpu);
|
||||||
CPUM68KState *env = &cpu->env;
|
CPUM68KState *env = &cpu->env;
|
||||||
|
|
||||||
if (m68k_feature(env, M68K_FEATURE_CF_FPU)) {
|
if (m68k_feature(env, M68K_FEATURE_CF_FPU)) {
|
||||||
gdb_register_coprocessor(env, fpu_gdb_get_reg, fpu_gdb_set_reg,
|
gdb_register_coprocessor(cs, fpu_gdb_get_reg, fpu_gdb_set_reg,
|
||||||
11, "cf-fp.xml", 18);
|
11, "cf-fp.xml", 18);
|
||||||
}
|
}
|
||||||
/* TODO: Add [E]MAC registers. */
|
/* TODO: Add [E]MAC registers. */
|
||||||
|
@ -290,7 +291,7 @@ int cpu_m68k_handle_mmu_fault (CPUM68KState *env, target_ulong address, int rw,
|
||||||
/* MMU */
|
/* MMU */
|
||||||
|
|
||||||
/* TODO: This will need fixing once the MMU is implemented. */
|
/* TODO: This will need fixing once the MMU is implemented. */
|
||||||
hwaddr cpu_get_phys_page_debug(CPUM68KState *env, target_ulong addr)
|
hwaddr m68k_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||||
{
|
{
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,8 +161,11 @@ static void m68k_semi_return_u64(CPUM68KState *env, uint64_t ret, uint32_t err)
|
||||||
|
|
||||||
static int m68k_semi_is_fseek;
|
static int m68k_semi_is_fseek;
|
||||||
|
|
||||||
static void m68k_semi_cb(CPUM68KState *env, target_ulong ret, target_ulong err)
|
static void m68k_semi_cb(CPUState *cs, target_ulong ret, target_ulong err)
|
||||||
{
|
{
|
||||||
|
M68kCPU *cpu = M68K_CPU(cs);
|
||||||
|
CPUM68KState *env = &cpu->env;
|
||||||
|
|
||||||
if (m68k_semi_is_fseek) {
|
if (m68k_semi_is_fseek) {
|
||||||
/* FIXME: We've already lost the high bits of the fseek
|
/* FIXME: We've already lost the high bits of the fseek
|
||||||
return value. */
|
return value. */
|
||||||
|
|
|
@ -2974,6 +2974,7 @@ static inline void
|
||||||
gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,
|
gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,
|
||||||
bool search_pc)
|
bool search_pc)
|
||||||
{
|
{
|
||||||
|
CPUState *cs = CPU(cpu);
|
||||||
CPUM68KState *env = &cpu->env;
|
CPUM68KState *env = &cpu->env;
|
||||||
DisasContext dc1, *dc = &dc1;
|
DisasContext dc1, *dc = &dc1;
|
||||||
uint16_t *gen_opc_end;
|
uint16_t *gen_opc_end;
|
||||||
|
@ -2995,7 +2996,7 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,
|
||||||
dc->is_jmp = DISAS_NEXT;
|
dc->is_jmp = DISAS_NEXT;
|
||||||
dc->pc = pc_start;
|
dc->pc = pc_start;
|
||||||
dc->cc_op = CC_OP_DYNAMIC;
|
dc->cc_op = CC_OP_DYNAMIC;
|
||||||
dc->singlestep_enabled = env->singlestep_enabled;
|
dc->singlestep_enabled = cs->singlestep_enabled;
|
||||||
dc->fpcr = env->fpcr;
|
dc->fpcr = env->fpcr;
|
||||||
dc->user = (env->sr & SR_S) == 0;
|
dc->user = (env->sr & SR_S) == 0;
|
||||||
dc->is_mem = 0;
|
dc->is_mem = 0;
|
||||||
|
@ -3038,14 +3039,14 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,
|
||||||
disas_m68k_insn(env, dc);
|
disas_m68k_insn(env, dc);
|
||||||
num_insns++;
|
num_insns++;
|
||||||
} while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
|
} while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
|
||||||
!env->singlestep_enabled &&
|
!cs->singlestep_enabled &&
|
||||||
!singlestep &&
|
!singlestep &&
|
||||||
(pc_offset) < (TARGET_PAGE_SIZE - 32) &&
|
(pc_offset) < (TARGET_PAGE_SIZE - 32) &&
|
||||||
num_insns < max_insns);
|
num_insns < max_insns);
|
||||||
|
|
||||||
if (tb->cflags & CF_LAST_IO)
|
if (tb->cflags & CF_LAST_IO)
|
||||||
gen_io_end();
|
gen_io_end();
|
||||||
if (unlikely(env->singlestep_enabled)) {
|
if (unlikely(cs->singlestep_enabled)) {
|
||||||
/* Make sure the pc is updated, and raise a debug exception. */
|
/* Make sure the pc is updated, and raise a debug exception. */
|
||||||
if (!dc->is_jmp) {
|
if (!dc->is_jmp) {
|
||||||
gen_flush_cc_op(dc);
|
gen_flush_cc_op(dc);
|
||||||
|
|
|
@ -74,5 +74,6 @@ static inline MicroBlazeCPU *mb_env_get_cpu(CPUMBState *env)
|
||||||
void mb_cpu_do_interrupt(CPUState *cs);
|
void mb_cpu_do_interrupt(CPUState *cs);
|
||||||
void mb_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
|
void mb_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
|
||||||
int flags);
|
int flags);
|
||||||
|
hwaddr mb_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -26,6 +26,13 @@
|
||||||
#include "migration/vmstate.h"
|
#include "migration/vmstate.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void mb_cpu_set_pc(CPUState *cs, vaddr value)
|
||||||
|
{
|
||||||
|
MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
|
||||||
|
|
||||||
|
cpu->env.sregs[SR_PC] = value;
|
||||||
|
}
|
||||||
|
|
||||||
/* CPUClass::reset() */
|
/* CPUClass::reset() */
|
||||||
static void mb_cpu_reset(CPUState *s)
|
static void mb_cpu_reset(CPUState *s)
|
||||||
{
|
{
|
||||||
|
@ -133,7 +140,11 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
|
||||||
|
|
||||||
cc->do_interrupt = mb_cpu_do_interrupt;
|
cc->do_interrupt = mb_cpu_do_interrupt;
|
||||||
cc->dump_state = mb_cpu_dump_state;
|
cc->dump_state = mb_cpu_dump_state;
|
||||||
cpu_class_set_do_unassigned_access(cc, mb_cpu_unassigned_access);
|
cc->set_pc = mb_cpu_set_pc;
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
cc->do_unassigned_access = mb_cpu_unassigned_access;
|
||||||
|
cc->get_phys_page_debug = mb_cpu_get_phys_page_debug;
|
||||||
|
#endif
|
||||||
dc->vmsd = &vmstate_mb_cpu;
|
dc->vmsd = &vmstate_mb_cpu;
|
||||||
dc->props = mb_properties;
|
dc->props = mb_properties;
|
||||||
}
|
}
|
||||||
|
|
|
@ -365,9 +365,4 @@ static inline bool cpu_has_work(CPUState *cpu)
|
||||||
|
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUMBState *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->sregs[SR_PC] = tb->pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -265,8 +265,10 @@ void mb_cpu_do_interrupt(CPUState *cs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hwaddr cpu_get_phys_page_debug(CPUMBState * env, target_ulong addr)
|
hwaddr mb_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||||
{
|
{
|
||||||
|
MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
|
||||||
|
CPUMBState *env = &cpu->env;
|
||||||
target_ulong vaddr, paddr = 0;
|
target_ulong vaddr, paddr = 0;
|
||||||
struct microblaze_mmu_lookup lu;
|
struct microblaze_mmu_lookup lu;
|
||||||
unsigned int hit;
|
unsigned int hit;
|
||||||
|
|
|
@ -1741,6 +1741,7 @@ static inline void
|
||||||
gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
|
gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
|
||||||
bool search_pc)
|
bool search_pc)
|
||||||
{
|
{
|
||||||
|
CPUState *cs = CPU(cpu);
|
||||||
CPUMBState *env = &cpu->env;
|
CPUMBState *env = &cpu->env;
|
||||||
uint16_t *gen_opc_end;
|
uint16_t *gen_opc_end;
|
||||||
uint32_t pc_start;
|
uint32_t pc_start;
|
||||||
|
@ -1766,7 +1767,7 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
|
||||||
dc->jmp = JMP_INDIRECT;
|
dc->jmp = JMP_INDIRECT;
|
||||||
}
|
}
|
||||||
dc->pc = pc_start;
|
dc->pc = pc_start;
|
||||||
dc->singlestep_enabled = env->singlestep_enabled;
|
dc->singlestep_enabled = cs->singlestep_enabled;
|
||||||
dc->cpustate_changed = 0;
|
dc->cpustate_changed = 0;
|
||||||
dc->abort_at_next_insn = 0;
|
dc->abort_at_next_insn = 0;
|
||||||
dc->nr_nops = 0;
|
dc->nr_nops = 0;
|
||||||
|
@ -1859,8 +1860,9 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (env->singlestep_enabled)
|
if (cs->singlestep_enabled) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
} while (!dc->is_jmp && !dc->cpustate_changed
|
} while (!dc->is_jmp && !dc->cpustate_changed
|
||||||
&& tcg_ctx.gen_opc_ptr < gen_opc_end
|
&& tcg_ctx.gen_opc_ptr < gen_opc_end
|
||||||
&& !singlestep
|
&& !singlestep
|
||||||
|
@ -1887,7 +1889,7 @@ gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
|
||||||
}
|
}
|
||||||
t_sync_flags(dc);
|
t_sync_flags(dc);
|
||||||
|
|
||||||
if (unlikely(env->singlestep_enabled)) {
|
if (unlikely(cs->singlestep_enabled)) {
|
||||||
TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
|
TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
|
||||||
|
|
||||||
if (dc->is_jmp != DISAS_JUMP) {
|
if (dc->is_jmp != DISAS_JUMP) {
|
||||||
|
|
|
@ -77,5 +77,6 @@ static inline MIPSCPU *mips_env_get_cpu(CPUMIPSState *env)
|
||||||
void mips_cpu_do_interrupt(CPUState *cpu);
|
void mips_cpu_do_interrupt(CPUState *cpu);
|
||||||
void mips_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
|
void mips_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
|
||||||
int flags);
|
int flags);
|
||||||
|
hwaddr mips_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,6 +22,29 @@
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void mips_cpu_set_pc(CPUState *cs, vaddr value)
|
||||||
|
{
|
||||||
|
MIPSCPU *cpu = MIPS_CPU(cs);
|
||||||
|
CPUMIPSState *env = &cpu->env;
|
||||||
|
|
||||||
|
env->active_tc.PC = value & ~(target_ulong)1;
|
||||||
|
if (value & 1) {
|
||||||
|
env->hflags |= MIPS_HFLAG_M16;
|
||||||
|
} else {
|
||||||
|
env->hflags &= ~(MIPS_HFLAG_M16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mips_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
|
||||||
|
{
|
||||||
|
MIPSCPU *cpu = MIPS_CPU(cs);
|
||||||
|
CPUMIPSState *env = &cpu->env;
|
||||||
|
|
||||||
|
env->active_tc.PC = tb->pc;
|
||||||
|
env->hflags &= ~MIPS_HFLAG_BMASK;
|
||||||
|
env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
|
||||||
|
}
|
||||||
|
|
||||||
/* CPUClass::reset() */
|
/* CPUClass::reset() */
|
||||||
static void mips_cpu_reset(CPUState *s)
|
static void mips_cpu_reset(CPUState *s)
|
||||||
{
|
{
|
||||||
|
@ -75,7 +98,12 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
|
||||||
|
|
||||||
cc->do_interrupt = mips_cpu_do_interrupt;
|
cc->do_interrupt = mips_cpu_do_interrupt;
|
||||||
cc->dump_state = mips_cpu_dump_state;
|
cc->dump_state = mips_cpu_dump_state;
|
||||||
cpu_class_set_do_unassigned_access(cc, mips_cpu_unassigned_access);
|
cc->set_pc = mips_cpu_set_pc;
|
||||||
|
cc->synchronize_from_tb = mips_cpu_synchronize_from_tb;
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
cc->do_unassigned_access = mips_cpu_unassigned_access;
|
||||||
|
cc->get_phys_page_debug = mips_cpu_get_phys_page_debug;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo mips_cpu_type_info = {
|
static const TypeInfo mips_cpu_type_info = {
|
||||||
|
|
|
@ -732,13 +732,6 @@ static inline bool cpu_has_work(CPUState *cpu)
|
||||||
|
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUMIPSState *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->active_tc.PC = tb->pc;
|
|
||||||
env->hflags &= ~MIPS_HFLAG_BMASK;
|
|
||||||
env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void compute_hflags(CPUMIPSState *env)
|
static inline void compute_hflags(CPUMIPSState *env)
|
||||||
{
|
{
|
||||||
env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
|
env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
|
||||||
|
|
|
@ -254,13 +254,16 @@ static void raise_mmu_exception(CPUMIPSState *env, target_ulong address,
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
hwaddr cpu_get_phys_page_debug(CPUMIPSState *env, target_ulong addr)
|
hwaddr mips_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||||
{
|
{
|
||||||
|
MIPSCPU *cpu = MIPS_CPU(cs);
|
||||||
hwaddr phys_addr;
|
hwaddr phys_addr;
|
||||||
int prot;
|
int prot;
|
||||||
|
|
||||||
if (get_physical_address(env, &phys_addr, &prot, addr, 0, ACCESS_INT) != 0)
|
if (get_physical_address(&cpu->env, &phys_addr, &prot, addr, 0,
|
||||||
|
ACCESS_INT) != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
return phys_addr;
|
return phys_addr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -15543,6 +15543,7 @@ static inline void
|
||||||
gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
|
gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
|
||||||
bool search_pc)
|
bool search_pc)
|
||||||
{
|
{
|
||||||
|
CPUState *cs = CPU(cpu);
|
||||||
CPUMIPSState *env = &cpu->env;
|
CPUMIPSState *env = &cpu->env;
|
||||||
DisasContext ctx;
|
DisasContext ctx;
|
||||||
target_ulong pc_start;
|
target_ulong pc_start;
|
||||||
|
@ -15561,7 +15562,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
|
||||||
gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
|
gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
|
||||||
ctx.pc = pc_start;
|
ctx.pc = pc_start;
|
||||||
ctx.saved_pc = -1;
|
ctx.saved_pc = -1;
|
||||||
ctx.singlestep_enabled = env->singlestep_enabled;
|
ctx.singlestep_enabled = cs->singlestep_enabled;
|
||||||
ctx.insn_flags = env->insn_flags;
|
ctx.insn_flags = env->insn_flags;
|
||||||
ctx.tb = tb;
|
ctx.tb = tb;
|
||||||
ctx.bstate = BS_NONE;
|
ctx.bstate = BS_NONE;
|
||||||
|
@ -15637,8 +15638,9 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
|
||||||
This is what GDB expects and is consistent with what the
|
This is what GDB expects and is consistent with what the
|
||||||
hardware does (e.g. if a delay slot instruction faults, the
|
hardware does (e.g. if a delay slot instruction faults, the
|
||||||
reported PC is the PC of the branch). */
|
reported PC is the PC of the branch). */
|
||||||
if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
|
if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
|
if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
|
||||||
break;
|
break;
|
||||||
|
@ -15653,9 +15655,10 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
|
||||||
if (singlestep)
|
if (singlestep)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (tb->cflags & CF_LAST_IO)
|
if (tb->cflags & CF_LAST_IO) {
|
||||||
gen_io_end();
|
gen_io_end();
|
||||||
if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
|
}
|
||||||
|
if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
|
||||||
save_cpu_state(&ctx, ctx.bstate == BS_NONE);
|
save_cpu_state(&ctx, ctx.bstate == BS_NONE);
|
||||||
gen_helper_0e0i(raise_exception, EXCP_DEBUG);
|
gen_helper_0e0i(raise_exception, EXCP_DEBUG);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -22,6 +22,13 @@
|
||||||
#include "migration/vmstate.h"
|
#include "migration/vmstate.h"
|
||||||
#include "machine.h"
|
#include "machine.h"
|
||||||
|
|
||||||
|
static void moxie_cpu_set_pc(CPUState *cs, vaddr value)
|
||||||
|
{
|
||||||
|
MoxieCPU *cpu = MOXIE_CPU(cs);
|
||||||
|
|
||||||
|
cpu->env.pc = value;
|
||||||
|
}
|
||||||
|
|
||||||
static void moxie_cpu_reset(CPUState *s)
|
static void moxie_cpu_reset(CPUState *s)
|
||||||
{
|
{
|
||||||
MoxieCPU *cpu = MOXIE_CPU(s);
|
MoxieCPU *cpu = MOXIE_CPU(s);
|
||||||
|
@ -93,7 +100,11 @@ static void moxie_cpu_class_init(ObjectClass *oc, void *data)
|
||||||
|
|
||||||
cc->do_interrupt = moxie_cpu_do_interrupt;
|
cc->do_interrupt = moxie_cpu_do_interrupt;
|
||||||
cc->dump_state = moxie_cpu_dump_state;
|
cc->dump_state = moxie_cpu_dump_state;
|
||||||
cpu_class_set_vmsd(cc, &vmstate_moxie_cpu);
|
cc->set_pc = moxie_cpu_set_pc;
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
cc->get_phys_page_debug = moxie_cpu_get_phys_page_debug;
|
||||||
|
cc->vmsd = &vmstate_moxie_cpu;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void moxielite_initfn(Object *obj)
|
static void moxielite_initfn(Object *obj)
|
||||||
|
|
|
@ -118,6 +118,7 @@ int cpu_moxie_exec(CPUMoxieState *s);
|
||||||
void moxie_cpu_do_interrupt(CPUState *cs);
|
void moxie_cpu_do_interrupt(CPUState *cs);
|
||||||
void moxie_cpu_dump_state(CPUState *cpu, FILE *f,
|
void moxie_cpu_dump_state(CPUState *cpu, FILE *f,
|
||||||
fprintf_function cpu_fprintf, int flags);
|
fprintf_function cpu_fprintf, int flags);
|
||||||
|
hwaddr moxie_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
|
||||||
void moxie_translate_init(void);
|
void moxie_translate_init(void);
|
||||||
int cpu_moxie_signal_handler(int host_signum, void *pinfo,
|
int cpu_moxie_signal_handler(int host_signum, void *pinfo,
|
||||||
void *puc);
|
void *puc);
|
||||||
|
@ -143,11 +144,6 @@ static inline int cpu_mmu_index(CPUMoxieState *env)
|
||||||
#include "exec/cpu-all.h"
|
#include "exec/cpu-all.h"
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUMoxieState *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->pc = tb->pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void cpu_get_tb_cpu_state(CPUMoxieState *env, target_ulong *pc,
|
static inline void cpu_get_tb_cpu_state(CPUMoxieState *env, target_ulong *pc,
|
||||||
target_ulong *cs_base, int *flags)
|
target_ulong *cs_base, int *flags)
|
||||||
{
|
{
|
||||||
|
|
|
@ -118,11 +118,6 @@ int cpu_moxie_handle_mmu_fault(CPUMoxieState *env, target_ulong address,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
hwaddr cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
|
|
||||||
{
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* !CONFIG_USER_ONLY */
|
#else /* !CONFIG_USER_ONLY */
|
||||||
|
|
||||||
int cpu_moxie_handle_mmu_fault(CPUMoxieState *env, target_ulong address,
|
int cpu_moxie_handle_mmu_fault(CPUMoxieState *env, target_ulong address,
|
||||||
|
@ -162,12 +157,14 @@ void moxie_cpu_do_interrupt(CPUState *cs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hwaddr cpu_get_phys_page_debug(CPUMoxieState *env, target_ulong addr)
|
hwaddr moxie_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||||
{
|
{
|
||||||
|
MoxieCPU *cpu = MOXIE_CPU(cs);
|
||||||
uint32_t phy = addr;
|
uint32_t phy = addr;
|
||||||
MoxieMMUResult res;
|
MoxieMMUResult res;
|
||||||
int miss;
|
int miss;
|
||||||
miss = moxie_mmu_translate(&res, env, addr, 0, 0);
|
|
||||||
|
miss = moxie_mmu_translate(&res, &cpu->env, addr, 0, 0);
|
||||||
if (!miss) {
|
if (!miss) {
|
||||||
phy = res.phy;
|
phy = res.phy;
|
||||||
}
|
}
|
||||||
|
|
|
@ -824,6 +824,7 @@ static inline void
|
||||||
gen_intermediate_code_internal(MoxieCPU *cpu, TranslationBlock *tb,
|
gen_intermediate_code_internal(MoxieCPU *cpu, TranslationBlock *tb,
|
||||||
bool search_pc)
|
bool search_pc)
|
||||||
{
|
{
|
||||||
|
CPUState *cs = CPU(cpu);
|
||||||
DisasContext ctx;
|
DisasContext ctx;
|
||||||
target_ulong pc_start;
|
target_ulong pc_start;
|
||||||
uint16_t *gen_opc_end;
|
uint16_t *gen_opc_end;
|
||||||
|
@ -871,7 +872,7 @@ gen_intermediate_code_internal(MoxieCPU *cpu, TranslationBlock *tb,
|
||||||
ctx.pc += decode_opc(cpu, &ctx);
|
ctx.pc += decode_opc(cpu, &ctx);
|
||||||
num_insns++;
|
num_insns++;
|
||||||
|
|
||||||
if (env->singlestep_enabled) {
|
if (cs->singlestep_enabled) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -880,7 +881,7 @@ gen_intermediate_code_internal(MoxieCPU *cpu, TranslationBlock *tb,
|
||||||
}
|
}
|
||||||
} while (ctx.bstate == BS_NONE && tcg_ctx.gen_opc_ptr < gen_opc_end);
|
} while (ctx.bstate == BS_NONE && tcg_ctx.gen_opc_ptr < gen_opc_end);
|
||||||
|
|
||||||
if (env->singlestep_enabled) {
|
if (cs->singlestep_enabled) {
|
||||||
tcg_gen_movi_tl(cpu_pc, ctx.pc);
|
tcg_gen_movi_tl(cpu_pc, ctx.pc);
|
||||||
gen_helper_debug(cpu_env);
|
gen_helper_debug(cpu_env);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -20,6 +20,13 @@
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
|
|
||||||
|
static void openrisc_cpu_set_pc(CPUState *cs, vaddr value)
|
||||||
|
{
|
||||||
|
OpenRISCCPU *cpu = OPENRISC_CPU(cs);
|
||||||
|
|
||||||
|
cpu->env.pc = value;
|
||||||
|
}
|
||||||
|
|
||||||
/* CPUClass::reset() */
|
/* CPUClass::reset() */
|
||||||
static void openrisc_cpu_reset(CPUState *s)
|
static void openrisc_cpu_reset(CPUState *s)
|
||||||
{
|
{
|
||||||
|
@ -146,7 +153,11 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
|
||||||
cc->class_by_name = openrisc_cpu_class_by_name;
|
cc->class_by_name = openrisc_cpu_class_by_name;
|
||||||
cc->do_interrupt = openrisc_cpu_do_interrupt;
|
cc->do_interrupt = openrisc_cpu_do_interrupt;
|
||||||
cc->dump_state = openrisc_cpu_dump_state;
|
cc->dump_state = openrisc_cpu_dump_state;
|
||||||
device_class_set_vmsd(dc, &vmstate_openrisc_cpu);
|
cc->set_pc = openrisc_cpu_set_pc;
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
cc->get_phys_page_debug = openrisc_cpu_get_phys_page_debug;
|
||||||
|
dc->vmsd = &vmstate_openrisc_cpu;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cpu_register(const OpenRISCCPUInfo *info)
|
static void cpu_register(const OpenRISCCPUInfo *info)
|
||||||
|
|
|
@ -349,6 +349,7 @@ int cpu_openrisc_exec(CPUOpenRISCState *s);
|
||||||
void openrisc_cpu_do_interrupt(CPUState *cpu);
|
void openrisc_cpu_do_interrupt(CPUState *cpu);
|
||||||
void openrisc_cpu_dump_state(CPUState *cpu, FILE *f,
|
void openrisc_cpu_dump_state(CPUState *cpu, FILE *f,
|
||||||
fprintf_function cpu_fprintf, int flags);
|
fprintf_function cpu_fprintf, int flags);
|
||||||
|
hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
|
||||||
void openrisc_translate_init(void);
|
void openrisc_translate_init(void);
|
||||||
int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env,
|
int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env,
|
||||||
target_ulong address,
|
target_ulong address,
|
||||||
|
@ -428,9 +429,4 @@ static inline target_ulong cpu_get_pc(CPUOpenRISCState *env)
|
||||||
return env->pc;
|
return env->pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUOpenRISCState *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->pc = tb->pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* CPU_OPENRISC_H */
|
#endif /* CPU_OPENRISC_H */
|
||||||
|
|
|
@ -219,12 +219,11 @@ int cpu_openrisc_handle_mmu_fault(CPUOpenRISCState *env,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
hwaddr cpu_get_phys_page_debug(CPUOpenRISCState *env,
|
hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||||
target_ulong addr)
|
|
||||||
{
|
{
|
||||||
|
OpenRISCCPU *cpu = OPENRISC_CPU(cs);
|
||||||
hwaddr phys_addr;
|
hwaddr phys_addr;
|
||||||
int prot;
|
int prot;
|
||||||
OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
|
|
||||||
|
|
||||||
if (cpu_openrisc_get_phys_addr(cpu, &phys_addr, &prot, addr, 0)) {
|
if (cpu_openrisc_get_phys_addr(cpu, &phys_addr, &prot, addr, 0)) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -1662,6 +1662,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
|
||||||
TranslationBlock *tb,
|
TranslationBlock *tb,
|
||||||
int search_pc)
|
int search_pc)
|
||||||
{
|
{
|
||||||
|
CPUState *cs = CPU(cpu);
|
||||||
struct DisasContext ctx, *dc = &ctx;
|
struct DisasContext ctx, *dc = &ctx;
|
||||||
uint16_t *gen_opc_end;
|
uint16_t *gen_opc_end;
|
||||||
uint32_t pc_start;
|
uint32_t pc_start;
|
||||||
|
@ -1681,7 +1682,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
|
||||||
dc->mem_idx = cpu_mmu_index(&cpu->env);
|
dc->mem_idx = cpu_mmu_index(&cpu->env);
|
||||||
dc->synced_flags = dc->tb_flags = tb->flags;
|
dc->synced_flags = dc->tb_flags = tb->flags;
|
||||||
dc->delayed_branch = !!(dc->tb_flags & D_FLAG);
|
dc->delayed_branch = !!(dc->tb_flags & D_FLAG);
|
||||||
dc->singlestep_enabled = cpu->env.singlestep_enabled;
|
dc->singlestep_enabled = cs->singlestep_enabled;
|
||||||
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
|
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
|
||||||
qemu_log("-----------------------------------------\n");
|
qemu_log("-----------------------------------------\n");
|
||||||
log_cpu_state(CPU(cpu), 0);
|
log_cpu_state(CPU(cpu), 0);
|
||||||
|
@ -1743,7 +1744,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
|
||||||
}
|
}
|
||||||
} while (!dc->is_jmp
|
} while (!dc->is_jmp
|
||||||
&& tcg_ctx.gen_opc_ptr < gen_opc_end
|
&& tcg_ctx.gen_opc_ptr < gen_opc_end
|
||||||
&& !cpu->env.singlestep_enabled
|
&& !cs->singlestep_enabled
|
||||||
&& !singlestep
|
&& !singlestep
|
||||||
&& (dc->pc < next_page_start)
|
&& (dc->pc < next_page_start)
|
||||||
&& num_insns < max_insns);
|
&& num_insns < max_insns);
|
||||||
|
@ -1755,7 +1756,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
|
||||||
dc->is_jmp = DISAS_UPDATE;
|
dc->is_jmp = DISAS_UPDATE;
|
||||||
tcg_gen_movi_tl(cpu_pc, dc->pc);
|
tcg_gen_movi_tl(cpu_pc, dc->pc);
|
||||||
}
|
}
|
||||||
if (unlikely(cpu->env.singlestep_enabled)) {
|
if (unlikely(cs->singlestep_enabled)) {
|
||||||
if (dc->is_jmp == DISAS_NEXT) {
|
if (dc->is_jmp == DISAS_NEXT) {
|
||||||
tcg_gen_movi_tl(cpu_pc, dc->pc);
|
tcg_gen_movi_tl(cpu_pc, dc->pc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,5 +105,6 @@ void ppc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
|
||||||
int flags);
|
int flags);
|
||||||
void ppc_cpu_dump_statistics(CPUState *cpu, FILE *f,
|
void ppc_cpu_dump_statistics(CPUState *cpu, FILE *f,
|
||||||
fprintf_function cpu_fprintf, int flags);
|
fprintf_function cpu_fprintf, int flags);
|
||||||
|
hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2144,11 +2144,6 @@ static inline bool cpu_has_work(CPUState *cpu)
|
||||||
|
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUPPCState *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->nip = tb->pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env);
|
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env);
|
||||||
|
|
||||||
#endif /* !defined (__CPU_PPC_H__) */
|
#endif /* !defined (__CPU_PPC_H__) */
|
||||||
|
|
|
@ -1409,8 +1409,10 @@ static int get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
hwaddr cpu_get_phys_page_debug(CPUPPCState *env, target_ulong addr)
|
hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||||
{
|
{
|
||||||
|
PowerPCCPU *cpu = POWERPC_CPU(cs);
|
||||||
|
CPUPPCState *env = &cpu->env;
|
||||||
mmu_ctx_t ctx;
|
mmu_ctx_t ctx;
|
||||||
|
|
||||||
switch (env->mmu_model) {
|
switch (env->mmu_model) {
|
||||||
|
|
|
@ -9730,6 +9730,7 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
|
||||||
TranslationBlock *tb,
|
TranslationBlock *tb,
|
||||||
bool search_pc)
|
bool search_pc)
|
||||||
{
|
{
|
||||||
|
CPUState *cs = CPU(cpu);
|
||||||
CPUPPCState *env = &cpu->env;
|
CPUPPCState *env = &cpu->env;
|
||||||
DisasContext ctx, *ctxp = &ctx;
|
DisasContext ctx, *ctxp = &ctx;
|
||||||
opc_handler_t **table, *handler;
|
opc_handler_t **table, *handler;
|
||||||
|
@ -9770,8 +9771,9 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
|
||||||
ctx.singlestep_enabled = 0;
|
ctx.singlestep_enabled = 0;
|
||||||
if ((env->flags & POWERPC_FLAG_BE) && msr_be)
|
if ((env->flags & POWERPC_FLAG_BE) && msr_be)
|
||||||
ctx.singlestep_enabled |= CPU_BRANCH_STEP;
|
ctx.singlestep_enabled |= CPU_BRANCH_STEP;
|
||||||
if (unlikely(env->singlestep_enabled))
|
if (unlikely(cs->singlestep_enabled)) {
|
||||||
ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
|
ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
|
||||||
|
}
|
||||||
#if defined (DO_SINGLE_STEP) && 0
|
#if defined (DO_SINGLE_STEP) && 0
|
||||||
/* Single step trace mode */
|
/* Single step trace mode */
|
||||||
msr_se = 1;
|
msr_se = 1;
|
||||||
|
@ -9873,7 +9875,7 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
|
||||||
ctx.exception != POWERPC_EXCP_BRANCH)) {
|
ctx.exception != POWERPC_EXCP_BRANCH)) {
|
||||||
gen_exception(ctxp, POWERPC_EXCP_TRACE);
|
gen_exception(ctxp, POWERPC_EXCP_TRACE);
|
||||||
} else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
|
} else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
|
||||||
(env->singlestep_enabled) ||
|
(cs->singlestep_enabled) ||
|
||||||
singlestep ||
|
singlestep ||
|
||||||
num_insns >= max_insns)) {
|
num_insns >= max_insns)) {
|
||||||
/* if we reach a page boundary or are single stepping, stop
|
/* if we reach a page boundary or are single stepping, stop
|
||||||
|
@ -9887,7 +9889,7 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
|
||||||
if (ctx.exception == POWERPC_EXCP_NONE) {
|
if (ctx.exception == POWERPC_EXCP_NONE) {
|
||||||
gen_goto_tb(&ctx, 0, ctx.nip);
|
gen_goto_tb(&ctx, 0, ctx.nip);
|
||||||
} else if (ctx.exception != POWERPC_EXCP_BRANCH) {
|
} else if (ctx.exception != POWERPC_EXCP_BRANCH) {
|
||||||
if (unlikely(env->singlestep_enabled)) {
|
if (unlikely(cs->singlestep_enabled)) {
|
||||||
gen_debug_exception(ctxp);
|
gen_debug_exception(ctxp);
|
||||||
}
|
}
|
||||||
/* Generate the return instruction */
|
/* Generate the return instruction */
|
||||||
|
|
|
@ -7804,8 +7804,8 @@ static int ppc_fixup_cpu(PowerPCCPU *cpu)
|
||||||
|
|
||||||
static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
|
static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
|
CPUState *cs = CPU(dev);
|
||||||
PowerPCCPU *cpu = POWERPC_CPU(dev);
|
PowerPCCPU *cpu = POWERPC_CPU(dev);
|
||||||
CPUPPCState *env = &cpu->env;
|
|
||||||
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
|
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
|
@ -7849,15 +7849,15 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||||
init_ppc_proc(cpu);
|
init_ppc_proc(cpu);
|
||||||
|
|
||||||
if (pcc->insns_flags & PPC_FLOAT) {
|
if (pcc->insns_flags & PPC_FLOAT) {
|
||||||
gdb_register_coprocessor(env, gdb_get_float_reg, gdb_set_float_reg,
|
gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg,
|
||||||
33, "power-fpu.xml", 0);
|
33, "power-fpu.xml", 0);
|
||||||
}
|
}
|
||||||
if (pcc->insns_flags & PPC_ALTIVEC) {
|
if (pcc->insns_flags & PPC_ALTIVEC) {
|
||||||
gdb_register_coprocessor(env, gdb_get_avr_reg, gdb_set_avr_reg,
|
gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg,
|
||||||
34, "power-altivec.xml", 0);
|
34, "power-altivec.xml", 0);
|
||||||
}
|
}
|
||||||
if (pcc->insns_flags & PPC_SPE) {
|
if (pcc->insns_flags & PPC_SPE) {
|
||||||
gdb_register_coprocessor(env, gdb_get_spe_reg, gdb_set_spe_reg,
|
gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg,
|
||||||
34, "power-spe.xml", 0);
|
34, "power-spe.xml", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7865,6 +7865,7 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||||
|
|
||||||
#if defined(PPC_DUMP_CPU)
|
#if defined(PPC_DUMP_CPU)
|
||||||
{
|
{
|
||||||
|
CPUPPCState *env = &cpu->env;
|
||||||
const char *mmu_model, *excp_model, *bus_model;
|
const char *mmu_model, *excp_model, *bus_model;
|
||||||
switch (env->mmu_model) {
|
switch (env->mmu_model) {
|
||||||
case POWERPC_MMU_32B:
|
case POWERPC_MMU_32B:
|
||||||
|
@ -8016,10 +8017,10 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||||
printf(" none\n");
|
printf(" none\n");
|
||||||
printf(" Time-base/decrementer clock source: %s\n",
|
printf(" Time-base/decrementer clock source: %s\n",
|
||||||
env->flags & POWERPC_FLAG_RTC_CLK ? "RTC clock" : "bus clock");
|
env->flags & POWERPC_FLAG_RTC_CLK ? "RTC clock" : "bus clock");
|
||||||
|
dump_ppc_insns(env);
|
||||||
|
dump_ppc_sprs(env);
|
||||||
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
dump_ppc_insns(env);
|
|
||||||
dump_ppc_sprs(env);
|
|
||||||
fflush(stdout);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8322,6 +8323,13 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
|
||||||
return cpu_list;
|
return cpu_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ppc_cpu_set_pc(CPUState *cs, vaddr value)
|
||||||
|
{
|
||||||
|
PowerPCCPU *cpu = POWERPC_CPU(cs);
|
||||||
|
|
||||||
|
cpu->env.nip = value;
|
||||||
|
}
|
||||||
|
|
||||||
/* CPUClass::reset() */
|
/* CPUClass::reset() */
|
||||||
static void ppc_cpu_reset(CPUState *s)
|
static void ppc_cpu_reset(CPUState *s)
|
||||||
{
|
{
|
||||||
|
@ -8449,6 +8457,10 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
|
||||||
cc->do_interrupt = ppc_cpu_do_interrupt;
|
cc->do_interrupt = ppc_cpu_do_interrupt;
|
||||||
cc->dump_state = ppc_cpu_dump_state;
|
cc->dump_state = ppc_cpu_dump_state;
|
||||||
cc->dump_statistics = ppc_cpu_dump_statistics;
|
cc->dump_statistics = ppc_cpu_dump_statistics;
|
||||||
|
cc->set_pc = ppc_cpu_set_pc;
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo ppc_cpu_type_info = {
|
static const TypeInfo ppc_cpu_type_info = {
|
||||||
|
|
|
@ -74,5 +74,6 @@ static inline S390CPU *s390_env_get_cpu(CPUS390XState *env)
|
||||||
void s390_cpu_do_interrupt(CPUState *cpu);
|
void s390_cpu_do_interrupt(CPUState *cpu);
|
||||||
void s390_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
|
void s390_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
|
||||||
int flags);
|
int flags);
|
||||||
|
hwaddr s390_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -58,6 +58,13 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void s390_cpu_set_pc(CPUState *cs, vaddr value)
|
||||||
|
{
|
||||||
|
S390CPU *cpu = S390_CPU(cs);
|
||||||
|
|
||||||
|
cpu->env.psw.addr = value;
|
||||||
|
}
|
||||||
|
|
||||||
/* CPUClass::reset() */
|
/* CPUClass::reset() */
|
||||||
static void s390_cpu_reset(CPUState *s)
|
static void s390_cpu_reset(CPUState *s)
|
||||||
{
|
{
|
||||||
|
@ -165,6 +172,10 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
|
||||||
|
|
||||||
cc->do_interrupt = s390_cpu_do_interrupt;
|
cc->do_interrupt = s390_cpu_do_interrupt;
|
||||||
cc->dump_state = s390_cpu_dump_state;
|
cc->dump_state = s390_cpu_dump_state;
|
||||||
|
cc->set_pc = s390_cpu_set_pc;
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
cc->get_phys_page_debug = s390_cpu_get_phys_page_debug;
|
||||||
|
#endif
|
||||||
dc->vmsd = &vmstate_s390_cpu;
|
dc->vmsd = &vmstate_s390_cpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1041,11 +1041,6 @@ static inline bool cpu_has_work(CPUState *cpu)
|
||||||
(env->psw.mask & PSW_MASK_EXT);
|
(env->psw.mask & PSW_MASK_EXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUS390XState *env, TranslationBlock* tb)
|
|
||||||
{
|
|
||||||
env->psw.addr = tb->pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* fpu_helper.c */
|
/* fpu_helper.c */
|
||||||
uint32_t set_cc_nz_f32(float32 v);
|
uint32_t set_cc_nz_f32(float32 v);
|
||||||
uint32_t set_cc_nz_f64(float64 v);
|
uint32_t set_cc_nz_f64(float64 v);
|
||||||
|
|
|
@ -417,9 +417,10 @@ int cpu_s390x_handle_mmu_fault(CPUS390XState *env, target_ulong orig_vaddr,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
hwaddr cpu_get_phys_page_debug(CPUS390XState *env,
|
hwaddr s390_cpu_get_phys_page_debug(CPUState *cs, vaddr vaddr)
|
||||||
target_ulong vaddr)
|
|
||||||
{
|
{
|
||||||
|
S390CPU *cpu = S390_CPU(cs);
|
||||||
|
CPUS390XState *env = &cpu->env;
|
||||||
target_ulong raddr;
|
target_ulong raddr;
|
||||||
int prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
|
int prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
|
||||||
int old_exc = env->exception_index;
|
int old_exc = env->exception_index;
|
||||||
|
|
|
@ -4740,6 +4740,7 @@ static inline void gen_intermediate_code_internal(S390CPU *cpu,
|
||||||
TranslationBlock *tb,
|
TranslationBlock *tb,
|
||||||
bool search_pc)
|
bool search_pc)
|
||||||
{
|
{
|
||||||
|
CPUState *cs = CPU(cpu);
|
||||||
CPUS390XState *env = &cpu->env;
|
CPUS390XState *env = &cpu->env;
|
||||||
DisasContext dc;
|
DisasContext dc;
|
||||||
target_ulong pc_start;
|
target_ulong pc_start;
|
||||||
|
@ -4761,7 +4762,7 @@ static inline void gen_intermediate_code_internal(S390CPU *cpu,
|
||||||
dc.tb = tb;
|
dc.tb = tb;
|
||||||
dc.pc = pc_start;
|
dc.pc = pc_start;
|
||||||
dc.cc_op = CC_OP_DYNAMIC;
|
dc.cc_op = CC_OP_DYNAMIC;
|
||||||
do_debug = dc.singlestep_enabled = env->singlestep_enabled;
|
do_debug = dc.singlestep_enabled = cs->singlestep_enabled;
|
||||||
|
|
||||||
gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
|
gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
|
||||||
|
|
||||||
|
@ -4818,7 +4819,7 @@ static inline void gen_intermediate_code_internal(S390CPU *cpu,
|
||||||
|| tcg_ctx.gen_opc_ptr >= gen_opc_end
|
|| tcg_ctx.gen_opc_ptr >= gen_opc_end
|
||||||
|| num_insns >= max_insns
|
|| num_insns >= max_insns
|
||||||
|| singlestep
|
|| singlestep
|
||||||
|| env->singlestep_enabled)) {
|
|| cs->singlestep_enabled)) {
|
||||||
status = EXIT_PC_STALE;
|
status = EXIT_PC_STALE;
|
||||||
}
|
}
|
||||||
} while (status == NO_EXIT);
|
} while (status == NO_EXIT);
|
||||||
|
|
|
@ -86,5 +86,6 @@ static inline SuperHCPU *sh_env_get_cpu(CPUSH4State *env)
|
||||||
void superh_cpu_do_interrupt(CPUState *cpu);
|
void superh_cpu_do_interrupt(CPUState *cpu);
|
||||||
void superh_cpu_dump_state(CPUState *cpu, FILE *f,
|
void superh_cpu_dump_state(CPUState *cpu, FILE *f,
|
||||||
fprintf_function cpu_fprintf, int flags);
|
fprintf_function cpu_fprintf, int flags);
|
||||||
|
hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,6 +24,21 @@
|
||||||
#include "migration/vmstate.h"
|
#include "migration/vmstate.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void superh_cpu_set_pc(CPUState *cs, vaddr value)
|
||||||
|
{
|
||||||
|
SuperHCPU *cpu = SUPERH_CPU(cs);
|
||||||
|
|
||||||
|
cpu->env.pc = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void superh_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
|
||||||
|
{
|
||||||
|
SuperHCPU *cpu = SUPERH_CPU(cs);
|
||||||
|
|
||||||
|
cpu->env.pc = tb->pc;
|
||||||
|
cpu->env.flags = tb->flags;
|
||||||
|
}
|
||||||
|
|
||||||
/* CPUClass::reset() */
|
/* CPUClass::reset() */
|
||||||
static void superh_cpu_reset(CPUState *s)
|
static void superh_cpu_reset(CPUState *s)
|
||||||
{
|
{
|
||||||
|
@ -269,6 +284,11 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
|
||||||
cc->class_by_name = superh_cpu_class_by_name;
|
cc->class_by_name = superh_cpu_class_by_name;
|
||||||
cc->do_interrupt = superh_cpu_do_interrupt;
|
cc->do_interrupt = superh_cpu_do_interrupt;
|
||||||
cc->dump_state = superh_cpu_dump_state;
|
cc->dump_state = superh_cpu_dump_state;
|
||||||
|
cc->set_pc = superh_cpu_set_pc;
|
||||||
|
cc->synchronize_from_tb = superh_cpu_synchronize_from_tb;
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
cc->get_phys_page_debug = superh_cpu_get_phys_page_debug;
|
||||||
|
#endif
|
||||||
dc->vmsd = &vmstate_sh_cpu;
|
dc->vmsd = &vmstate_sh_cpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -359,10 +359,4 @@ static inline bool cpu_has_work(CPUState *cpu)
|
||||||
|
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUSH4State *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->pc = tb->pc;
|
|
||||||
env->flags = tb->flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* _CPU_SH4_H */
|
#endif /* _CPU_SH4_H */
|
||||||
|
|
|
@ -508,12 +508,13 @@ int cpu_sh4_handle_mmu_fault(CPUSH4State * env, target_ulong address, int rw,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
hwaddr cpu_get_phys_page_debug(CPUSH4State * env, target_ulong addr)
|
hwaddr superh_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||||
{
|
{
|
||||||
|
SuperHCPU *cpu = SUPERH_CPU(cs);
|
||||||
target_ulong physical;
|
target_ulong physical;
|
||||||
int prot;
|
int prot;
|
||||||
|
|
||||||
get_physical_address(env, &physical, &prot, addr, 0, 0);
|
get_physical_address(&cpu->env, &physical, &prot, addr, 0, 0);
|
||||||
return physical;
|
return physical;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1849,6 +1849,7 @@ static inline void
|
||||||
gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb,
|
gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb,
|
||||||
bool search_pc)
|
bool search_pc)
|
||||||
{
|
{
|
||||||
|
CPUState *cs = CPU(cpu);
|
||||||
CPUSH4State *env = &cpu->env;
|
CPUSH4State *env = &cpu->env;
|
||||||
DisasContext ctx;
|
DisasContext ctx;
|
||||||
target_ulong pc_start;
|
target_ulong pc_start;
|
||||||
|
@ -1868,7 +1869,7 @@ gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb,
|
||||||
so assume it is a dynamic branch. */
|
so assume it is a dynamic branch. */
|
||||||
ctx.delayed_pc = -1; /* use delayed pc from env pointer */
|
ctx.delayed_pc = -1; /* use delayed pc from env pointer */
|
||||||
ctx.tb = tb;
|
ctx.tb = tb;
|
||||||
ctx.singlestep_enabled = env->singlestep_enabled;
|
ctx.singlestep_enabled = cs->singlestep_enabled;
|
||||||
ctx.features = env->features;
|
ctx.features = env->features;
|
||||||
ctx.has_movcal = (ctx.flags & TB_FLAG_PENDING_MOVCA);
|
ctx.has_movcal = (ctx.flags & TB_FLAG_PENDING_MOVCA);
|
||||||
|
|
||||||
|
@ -1914,8 +1915,9 @@ gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb,
|
||||||
ctx.pc += 2;
|
ctx.pc += 2;
|
||||||
if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
|
if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
|
||||||
break;
|
break;
|
||||||
if (env->singlestep_enabled)
|
if (cs->singlestep_enabled) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
if (num_insns >= max_insns)
|
if (num_insns >= max_insns)
|
||||||
break;
|
break;
|
||||||
if (singlestep)
|
if (singlestep)
|
||||||
|
@ -1923,7 +1925,7 @@ gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb,
|
||||||
}
|
}
|
||||||
if (tb->cflags & CF_LAST_IO)
|
if (tb->cflags & CF_LAST_IO)
|
||||||
gen_io_end();
|
gen_io_end();
|
||||||
if (env->singlestep_enabled) {
|
if (cs->singlestep_enabled) {
|
||||||
tcg_gen_movi_i32(cpu_pc, ctx.pc);
|
tcg_gen_movi_i32(cpu_pc, ctx.pc);
|
||||||
gen_helper_debug(cpu_env);
|
gen_helper_debug(cpu_env);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -78,5 +78,6 @@ static inline SPARCCPU *sparc_env_get_cpu(CPUSPARCState *env)
|
||||||
void sparc_cpu_do_interrupt(CPUState *cpu);
|
void sparc_cpu_do_interrupt(CPUState *cpu);
|
||||||
void sparc_cpu_dump_state(CPUState *cpu, FILE *f,
|
void sparc_cpu_dump_state(CPUState *cpu, FILE *f,
|
||||||
fprintf_function cpu_fprintf, int flags);
|
fprintf_function cpu_fprintf, int flags);
|
||||||
|
hwaddr sparc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -723,6 +723,22 @@ void sparc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
|
||||||
cpu_fprintf(f, "\n");
|
cpu_fprintf(f, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sparc_cpu_set_pc(CPUState *cs, vaddr value)
|
||||||
|
{
|
||||||
|
SPARCCPU *cpu = SPARC_CPU(cs);
|
||||||
|
|
||||||
|
cpu->env.pc = value;
|
||||||
|
cpu->env.npc = value + 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sparc_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
|
||||||
|
{
|
||||||
|
SPARCCPU *cpu = SPARC_CPU(cs);
|
||||||
|
|
||||||
|
cpu->env.pc = tb->pc;
|
||||||
|
cpu->env.npc = tb->cs_base;
|
||||||
|
}
|
||||||
|
|
||||||
static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
|
static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(dev);
|
SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(dev);
|
||||||
|
@ -766,7 +782,15 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
|
||||||
|
|
||||||
cc->do_interrupt = sparc_cpu_do_interrupt;
|
cc->do_interrupt = sparc_cpu_do_interrupt;
|
||||||
cc->dump_state = sparc_cpu_dump_state;
|
cc->dump_state = sparc_cpu_dump_state;
|
||||||
cpu_class_set_do_unassigned_access(cc, sparc_cpu_unassigned_access);
|
#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
|
||||||
|
cc->memory_rw_debug = sparc_cpu_memory_rw_debug;
|
||||||
|
#endif
|
||||||
|
cc->set_pc = sparc_cpu_set_pc;
|
||||||
|
cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb;
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
cc->do_unassigned_access = sparc_cpu_unassigned_access;
|
||||||
|
cc->get_phys_page_debug = sparc_cpu_get_phys_page_debug;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo sparc_cpu_type_info = {
|
static const TypeInfo sparc_cpu_type_info = {
|
||||||
|
|
|
@ -526,9 +526,8 @@ target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev);
|
||||||
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env);
|
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env);
|
||||||
|
|
||||||
#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
|
#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
|
||||||
int target_memory_rw_debug(CPUSPARCState *env, target_ulong addr,
|
int sparc_cpu_memory_rw_debug(CPUState *cpu, vaddr addr,
|
||||||
uint8_t *buf, int len, int is_write);
|
uint8_t *buf, int len, bool is_write);
|
||||||
#define TARGET_CPU_MEMORY_RW_DEBUG
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -759,10 +758,4 @@ static inline bool cpu_has_work(CPUState *cpu)
|
||||||
|
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUSPARCState *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->pc = tb->pc;
|
|
||||||
env->npc = tb->cs_base;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -310,6 +310,7 @@ target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev)
|
||||||
|
|
||||||
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env)
|
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env)
|
||||||
{
|
{
|
||||||
|
CPUState *cs = CPU(sparc_env_get_cpu(env));
|
||||||
target_ulong va, va1, va2;
|
target_ulong va, va1, va2;
|
||||||
unsigned int n, m, o;
|
unsigned int n, m, o;
|
||||||
hwaddr pde_ptr, pa;
|
hwaddr pde_ptr, pa;
|
||||||
|
@ -322,20 +323,20 @@ void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env)
|
||||||
for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) {
|
for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) {
|
||||||
pde = mmu_probe(env, va, 2);
|
pde = mmu_probe(env, va, 2);
|
||||||
if (pde) {
|
if (pde) {
|
||||||
pa = cpu_get_phys_page_debug(env, va);
|
pa = cpu_get_phys_page_debug(cs, va);
|
||||||
(*cpu_fprintf)(f, "VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
|
(*cpu_fprintf)(f, "VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
|
||||||
" PDE: " TARGET_FMT_lx "\n", va, pa, pde);
|
" PDE: " TARGET_FMT_lx "\n", va, pa, pde);
|
||||||
for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) {
|
for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) {
|
||||||
pde = mmu_probe(env, va1, 1);
|
pde = mmu_probe(env, va1, 1);
|
||||||
if (pde) {
|
if (pde) {
|
||||||
pa = cpu_get_phys_page_debug(env, va1);
|
pa = cpu_get_phys_page_debug(cs, va1);
|
||||||
(*cpu_fprintf)(f, " VA: " TARGET_FMT_lx ", PA: "
|
(*cpu_fprintf)(f, " VA: " TARGET_FMT_lx ", PA: "
|
||||||
TARGET_FMT_plx " PDE: " TARGET_FMT_lx "\n",
|
TARGET_FMT_plx " PDE: " TARGET_FMT_lx "\n",
|
||||||
va1, pa, pde);
|
va1, pa, pde);
|
||||||
for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) {
|
for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) {
|
||||||
pde = mmu_probe(env, va2, 0);
|
pde = mmu_probe(env, va2, 0);
|
||||||
if (pde) {
|
if (pde) {
|
||||||
pa = cpu_get_phys_page_debug(env, va2);
|
pa = cpu_get_phys_page_debug(cs, va2);
|
||||||
(*cpu_fprintf)(f, " VA: " TARGET_FMT_lx ", PA: "
|
(*cpu_fprintf)(f, " VA: " TARGET_FMT_lx ", PA: "
|
||||||
TARGET_FMT_plx " PTE: "
|
TARGET_FMT_plx " PTE: "
|
||||||
TARGET_FMT_lx "\n",
|
TARGET_FMT_lx "\n",
|
||||||
|
@ -352,9 +353,12 @@ void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env)
|
||||||
* reads (and only reads) in stack frames as if windows were flushed. We assume
|
* reads (and only reads) in stack frames as if windows were flushed. We assume
|
||||||
* that the sparc ABI is followed.
|
* that the sparc ABI is followed.
|
||||||
*/
|
*/
|
||||||
int target_memory_rw_debug(CPUSPARCState *env, target_ulong addr,
|
int sparc_cpu_memory_rw_debug(CPUState *cs, vaddr address,
|
||||||
uint8_t *buf, int len, int is_write)
|
uint8_t *buf, int len, bool is_write)
|
||||||
{
|
{
|
||||||
|
SPARCCPU *cpu = SPARC_CPU(cs);
|
||||||
|
CPUSPARCState *env = &cpu->env;
|
||||||
|
target_ulong addr = address;
|
||||||
int i;
|
int i;
|
||||||
int len1;
|
int len1;
|
||||||
int cwp = env->cwp;
|
int cwp = env->cwp;
|
||||||
|
@ -389,7 +393,7 @@ int target_memory_rw_debug(CPUSPARCState *env, target_ulong addr,
|
||||||
/* Handle access before this window. */
|
/* Handle access before this window. */
|
||||||
if (addr < fp) {
|
if (addr < fp) {
|
||||||
len1 = fp - addr;
|
len1 = fp - addr;
|
||||||
if (cpu_memory_rw_debug(env, addr, buf, len1, is_write) != 0) {
|
if (cpu_memory_rw_debug(cs, addr, buf, len1, is_write) != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
addr += len1;
|
addr += len1;
|
||||||
|
@ -425,7 +429,7 @@ int target_memory_rw_debug(CPUSPARCState *env, target_ulong addr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return cpu_memory_rw_debug(env, addr, buf, len, is_write);
|
return cpu_memory_rw_debug(cs, addr, buf, len, is_write);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* !TARGET_SPARC64 */
|
#else /* !TARGET_SPARC64 */
|
||||||
|
@ -833,8 +837,10 @@ hwaddr cpu_get_phys_page_nofault(CPUSPARCState *env, target_ulong addr,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
hwaddr cpu_get_phys_page_debug(CPUSPARCState *env, target_ulong addr)
|
hwaddr sparc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||||
{
|
{
|
||||||
|
SPARCCPU *cpu = SPARC_CPU(cs);
|
||||||
|
CPUSPARCState *env = &cpu->env;
|
||||||
hwaddr phys_addr;
|
hwaddr phys_addr;
|
||||||
int mmu_idx = cpu_mmu_index(env);
|
int mmu_idx = cpu_mmu_index(env);
|
||||||
MemoryRegionSection section;
|
MemoryRegionSection section;
|
||||||
|
|
|
@ -5223,6 +5223,7 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
|
||||||
TranslationBlock *tb,
|
TranslationBlock *tb,
|
||||||
bool spc)
|
bool spc)
|
||||||
{
|
{
|
||||||
|
CPUState *cs = CPU(cpu);
|
||||||
CPUSPARCState *env = &cpu->env;
|
CPUSPARCState *env = &cpu->env;
|
||||||
target_ulong pc_start, last_pc;
|
target_ulong pc_start, last_pc;
|
||||||
uint16_t *gen_opc_end;
|
uint16_t *gen_opc_end;
|
||||||
|
@ -5244,7 +5245,7 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu,
|
||||||
dc->def = env->def;
|
dc->def = env->def;
|
||||||
dc->fpu_enabled = tb_fpu_enabled(tb->flags);
|
dc->fpu_enabled = tb_fpu_enabled(tb->flags);
|
||||||
dc->address_mask_32bit = tb_am_enabled(tb->flags);
|
dc->address_mask_32bit = tb_am_enabled(tb->flags);
|
||||||
dc->singlestep = (env->singlestep_enabled || singlestep);
|
dc->singlestep = (cs->singlestep_enabled || singlestep);
|
||||||
gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
|
gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
|
||||||
|
|
||||||
num_insns = 0;
|
num_insns = 0;
|
||||||
|
|
|
@ -63,5 +63,6 @@ static inline UniCore32CPU *uc32_env_get_cpu(CPUUniCore32State *env)
|
||||||
void uc32_cpu_do_interrupt(CPUState *cpu);
|
void uc32_cpu_do_interrupt(CPUState *cpu);
|
||||||
void uc32_cpu_dump_state(CPUState *cpu, FILE *f,
|
void uc32_cpu_dump_state(CPUState *cpu, FILE *f,
|
||||||
fprintf_function cpu_fprintf, int flags);
|
fprintf_function cpu_fprintf, int flags);
|
||||||
|
hwaddr uc32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,6 +16,13 @@
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "migration/vmstate.h"
|
#include "migration/vmstate.h"
|
||||||
|
|
||||||
|
static void uc32_cpu_set_pc(CPUState *cs, vaddr value)
|
||||||
|
{
|
||||||
|
UniCore32CPU *cpu = UNICORE32_CPU(cs);
|
||||||
|
|
||||||
|
cpu->env.regs[31] = value;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void set_feature(CPUUniCore32State *env, int feature)
|
static inline void set_feature(CPUUniCore32State *env, int feature)
|
||||||
{
|
{
|
||||||
env->features |= feature;
|
env->features |= feature;
|
||||||
|
@ -131,6 +138,10 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data)
|
||||||
cc->class_by_name = uc32_cpu_class_by_name;
|
cc->class_by_name = uc32_cpu_class_by_name;
|
||||||
cc->do_interrupt = uc32_cpu_do_interrupt;
|
cc->do_interrupt = uc32_cpu_do_interrupt;
|
||||||
cc->dump_state = uc32_cpu_dump_state;
|
cc->dump_state = uc32_cpu_dump_state;
|
||||||
|
cc->set_pc = uc32_cpu_set_pc;
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
cc->get_phys_page_debug = uc32_cpu_get_phys_page_debug;
|
||||||
|
#endif
|
||||||
dc->vmsd = &vmstate_uc32_cpu;
|
dc->vmsd = &vmstate_uc32_cpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -146,11 +146,6 @@ static inline int cpu_mmu_index(CPUUniCore32State *env)
|
||||||
#include "cpu-qom.h"
|
#include "cpu-qom.h"
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
|
||||||
static inline void cpu_pc_from_tb(CPUUniCore32State *env, TranslationBlock *tb)
|
|
||||||
{
|
|
||||||
env->regs[31] = tb->pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void cpu_get_tb_cpu_state(CPUUniCore32State *env, target_ulong *pc,
|
static inline void cpu_get_tb_cpu_state(CPUUniCore32State *env, target_ulong *pc,
|
||||||
target_ulong *cs_base, int *flags)
|
target_ulong *cs_base, int *flags)
|
||||||
{
|
{
|
||||||
|
|
|
@ -261,9 +261,10 @@ int uc32_cpu_handle_mmu_fault(CPUUniCore32State *env, target_ulong address,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
hwaddr cpu_get_phys_page_debug(CPUUniCore32State *env,
|
hwaddr uc32_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
|
||||||
target_ulong addr)
|
|
||||||
{
|
{
|
||||||
cpu_abort(env, "%s not supported yet\n", __func__);
|
UniCore32CPU *cpu = UNICORE32_CPU(cs);
|
||||||
|
|
||||||
|
cpu_abort(&cpu->env, "%s not supported yet\n", __func__);
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1879,6 +1879,7 @@ static void disas_uc32_insn(CPUUniCore32State *env, DisasContext *s)
|
||||||
static inline void gen_intermediate_code_internal(UniCore32CPU *cpu,
|
static inline void gen_intermediate_code_internal(UniCore32CPU *cpu,
|
||||||
TranslationBlock *tb, bool search_pc)
|
TranslationBlock *tb, bool search_pc)
|
||||||
{
|
{
|
||||||
|
CPUState *cs = CPU(cpu);
|
||||||
CPUUniCore32State *env = &cpu->env;
|
CPUUniCore32State *env = &cpu->env;
|
||||||
DisasContext dc1, *dc = &dc1;
|
DisasContext dc1, *dc = &dc1;
|
||||||
CPUBreakpoint *bp;
|
CPUBreakpoint *bp;
|
||||||
|
@ -1900,7 +1901,7 @@ static inline void gen_intermediate_code_internal(UniCore32CPU *cpu,
|
||||||
|
|
||||||
dc->is_jmp = DISAS_NEXT;
|
dc->is_jmp = DISAS_NEXT;
|
||||||
dc->pc = pc_start;
|
dc->pc = pc_start;
|
||||||
dc->singlestep_enabled = env->singlestep_enabled;
|
dc->singlestep_enabled = cs->singlestep_enabled;
|
||||||
dc->condjmp = 0;
|
dc->condjmp = 0;
|
||||||
cpu_F0s = tcg_temp_new_i32();
|
cpu_F0s = tcg_temp_new_i32();
|
||||||
cpu_F1s = tcg_temp_new_i32();
|
cpu_F1s = tcg_temp_new_i32();
|
||||||
|
@ -1971,7 +1972,7 @@ static inline void gen_intermediate_code_internal(UniCore32CPU *cpu,
|
||||||
* ensures prefetch aborts occur at the right place. */
|
* ensures prefetch aborts occur at the right place. */
|
||||||
num_insns++;
|
num_insns++;
|
||||||
} while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
|
} while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
|
||||||
!env->singlestep_enabled &&
|
!cs->singlestep_enabled &&
|
||||||
!singlestep &&
|
!singlestep &&
|
||||||
dc->pc < next_page_start &&
|
dc->pc < next_page_start &&
|
||||||
num_insns < max_insns);
|
num_insns < max_insns);
|
||||||
|
@ -1988,7 +1989,7 @@ static inline void gen_intermediate_code_internal(UniCore32CPU *cpu,
|
||||||
/* At this stage dc->condjmp will only be set when the skipped
|
/* At this stage dc->condjmp will only be set when the skipped
|
||||||
instruction was a conditional branch or trap, and the PC has
|
instruction was a conditional branch or trap, and the PC has
|
||||||
already been written. */
|
already been written. */
|
||||||
if (unlikely(env->singlestep_enabled)) {
|
if (unlikely(cs->singlestep_enabled)) {
|
||||||
/* Make sure the pc is updated, and raise a debug exception. */
|
/* Make sure the pc is updated, and raise a debug exception. */
|
||||||
if (dc->condjmp) {
|
if (dc->condjmp) {
|
||||||
if (dc->is_jmp == DISAS_SYSCALL) {
|
if (dc->is_jmp == DISAS_SYSCALL) {
|
||||||
|
|
|
@ -83,5 +83,6 @@ static inline XtensaCPU *xtensa_env_get_cpu(const CPUXtensaState *env)
|
||||||
void xtensa_cpu_do_interrupt(CPUState *cpu);
|
void xtensa_cpu_do_interrupt(CPUState *cpu);
|
||||||
void xtensa_cpu_dump_state(CPUState *cpu, FILE *f,
|
void xtensa_cpu_dump_state(CPUState *cpu, FILE *f,
|
||||||
fprintf_function cpu_fprintf, int flags);
|
fprintf_function cpu_fprintf, int flags);
|
||||||
|
hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -33,6 +33,13 @@
|
||||||
#include "migration/vmstate.h"
|
#include "migration/vmstate.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void xtensa_cpu_set_pc(CPUState *cs, vaddr value)
|
||||||
|
{
|
||||||
|
XtensaCPU *cpu = XTENSA_CPU(cs);
|
||||||
|
|
||||||
|
cpu->env.pc = value;
|
||||||
|
}
|
||||||
|
|
||||||
/* CPUClass::reset() */
|
/* CPUClass::reset() */
|
||||||
static void xtensa_cpu_reset(CPUState *s)
|
static void xtensa_cpu_reset(CPUState *s)
|
||||||
{
|
{
|
||||||
|
@ -100,6 +107,10 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
|
||||||
|
|
||||||
cc->do_interrupt = xtensa_cpu_do_interrupt;
|
cc->do_interrupt = xtensa_cpu_do_interrupt;
|
||||||
cc->dump_state = xtensa_cpu_dump_state;
|
cc->dump_state = xtensa_cpu_dump_state;
|
||||||
|
cc->set_pc = xtensa_cpu_set_pc;
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
cc->get_phys_page_debug = xtensa_cpu_get_phys_page_debug;
|
||||||
|
#endif
|
||||||
dc->vmsd = &vmstate_xtensa_cpu;
|
dc->vmsd = &vmstate_xtensa_cpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue