tcg: Allow first half of insn in ram, and second half in mmio
linux-user/sparc: SIGILL for unknown trap vectors linux-user/microblaze: SIGILL for privileged insns linux-user: Fix deadlock while exiting due to signal target/microblaze: Add gdbstub xml util: Adjust cacheflush for windows-arm64 include/sysemu/os-win32: Adjust setjmp/longjmp for windows-arm64 -----BEGIN PGP SIGNATURE----- iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmP1dpkdHHJpY2hhcmQu aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV+70gf+OOM3KmsFpsJ4+68W v/ulVwye3RFQXv4KRtuRPeKCKMk7vXmBRj9gsyOpc23TaoYiMNbFbztpAkcc/Z/1 +6H8QeZGLWDqiX6ashwGNm/2bqPbvY7znaCvNuLkNGCPBeJ12C19uN1BBiGdeqOe IXIIk1r0U6rfIDhP2PJALXOxgHd/8/onYbhU6kU5tQjM24pycW44UUGPSeV++I0e xWezAYOmZ4PK58bXHDPMZ0UkzuefaNmiLlfwj/4nlaWQetwQTy7BeEU6FpKolUN2 wrvfCqth/c3SdUaZHu4DoX1yWt72L37SpO0ijvk8E+AqsvXTn9gFdWK2dsEiPEeS Z9abFw== =dxZo -----END PGP SIGNATURE----- Merge tag 'pull-tcg-20230221' of https://gitlab.com/rth7680/qemu into staging tcg: Allow first half of insn in ram, and second half in mmio linux-user/sparc: SIGILL for unknown trap vectors linux-user/microblaze: SIGILL for privileged insns linux-user: Fix deadlock while exiting due to signal target/microblaze: Add gdbstub xml util: Adjust cacheflush for windows-arm64 include/sysemu/os-win32: Adjust setjmp/longjmp for windows-arm64 # -----BEGIN PGP SIGNATURE----- # # iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmP1dpkdHHJpY2hhcmQu # aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV+70gf+OOM3KmsFpsJ4+68W # v/ulVwye3RFQXv4KRtuRPeKCKMk7vXmBRj9gsyOpc23TaoYiMNbFbztpAkcc/Z/1 # +6H8QeZGLWDqiX6ashwGNm/2bqPbvY7znaCvNuLkNGCPBeJ12C19uN1BBiGdeqOe # IXIIk1r0U6rfIDhP2PJALXOxgHd/8/onYbhU6kU5tQjM24pycW44UUGPSeV++I0e # xWezAYOmZ4PK58bXHDPMZ0UkzuefaNmiLlfwj/4nlaWQetwQTy7BeEU6FpKolUN2 # wrvfCqth/c3SdUaZHu4DoX1yWt72L37SpO0ijvk8E+AqsvXTn9gFdWK2dsEiPEeS # Z9abFw== # =dxZo # -----END PGP SIGNATURE----- # gpg: Signature made Wed 22 Feb 2023 01:57:45 GMT # gpg: using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F # gpg: issuer "richard.henderson@linaro.org" # gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [full] # Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A 05C0 64DF 38E8 AF7E 215F * tag 'pull-tcg-20230221' of https://gitlab.com/rth7680/qemu: sysemu/os-win32: fix setjmp/longjmp on windows-arm64 util/cacheflush: fix cache on windows-arm64 target/microblaze: Add gdbstub xml linux-user/microblaze: Handle privileged exception cpus: Make {start,end}_exclusive() recursive linux-user: Always exit from exclusive state in fork_end() linux-user/sparc: Raise SIGILL for all unhandled software traps accel/tcg: Allow the second page of an instruction to be MMIO Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
ed9128c177
@ -176,8 +176,16 @@ static void *translator_access(CPUArchState *env, DisasContextBase *db,
|
|||||||
if (host == NULL) {
|
if (host == NULL) {
|
||||||
tb_page_addr_t phys_page =
|
tb_page_addr_t phys_page =
|
||||||
get_page_addr_code_hostp(env, base, &db->host_addr[1]);
|
get_page_addr_code_hostp(env, base, &db->host_addr[1]);
|
||||||
/* We cannot handle MMIO as second page. */
|
|
||||||
assert(phys_page != -1);
|
/*
|
||||||
|
* If the second page is MMIO, treat as if the first page
|
||||||
|
* was MMIO as well, so that we do not cache the TB.
|
||||||
|
*/
|
||||||
|
if (unlikely(phys_page == -1)) {
|
||||||
|
tb_set_page_addr0(tb, -1);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
tb_set_page_addr1(tb, phys_page);
|
tb_set_page_addr1(tb, phys_page);
|
||||||
#ifdef CONFIG_USER_ONLY
|
#ifdef CONFIG_USER_ONLY
|
||||||
page_protect(end);
|
page_protect(end);
|
||||||
|
@ -3,3 +3,4 @@ TARGET_SYSTBL_ABI=common
|
|||||||
TARGET_SYSTBL=syscall.tbl
|
TARGET_SYSTBL=syscall.tbl
|
||||||
TARGET_BIG_ENDIAN=y
|
TARGET_BIG_ENDIAN=y
|
||||||
TARGET_HAS_BFLT=y
|
TARGET_HAS_BFLT=y
|
||||||
|
TARGET_XML_FILES=gdb-xml/microblaze-core.xml gdb-xml/microblaze-stack-protect.xml
|
||||||
|
@ -2,3 +2,4 @@ TARGET_ARCH=microblaze
|
|||||||
TARGET_BIG_ENDIAN=y
|
TARGET_BIG_ENDIAN=y
|
||||||
TARGET_SUPPORTS_MTTCG=y
|
TARGET_SUPPORTS_MTTCG=y
|
||||||
TARGET_NEED_FDT=y
|
TARGET_NEED_FDT=y
|
||||||
|
TARGET_XML_FILES=gdb-xml/microblaze-core.xml gdb-xml/microblaze-stack-protect.xml
|
||||||
|
@ -2,3 +2,4 @@ TARGET_ARCH=microblaze
|
|||||||
TARGET_SYSTBL_ABI=common
|
TARGET_SYSTBL_ABI=common
|
||||||
TARGET_SYSTBL=syscall.tbl
|
TARGET_SYSTBL=syscall.tbl
|
||||||
TARGET_HAS_BFLT=y
|
TARGET_HAS_BFLT=y
|
||||||
|
TARGET_XML_FILES=gdb-xml/microblaze-core.xml gdb-xml/microblaze-stack-protect.xml
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
TARGET_ARCH=microblaze
|
TARGET_ARCH=microblaze
|
||||||
TARGET_SUPPORTS_MTTCG=y
|
TARGET_SUPPORTS_MTTCG=y
|
||||||
TARGET_NEED_FDT=y
|
TARGET_NEED_FDT=y
|
||||||
|
TARGET_XML_FILES=gdb-xml/microblaze-core.xml gdb-xml/microblaze-stack-protect.xml
|
||||||
|
@ -192,6 +192,11 @@ void start_exclusive(void)
|
|||||||
CPUState *other_cpu;
|
CPUState *other_cpu;
|
||||||
int running_cpus;
|
int running_cpus;
|
||||||
|
|
||||||
|
if (current_cpu->exclusive_context_count) {
|
||||||
|
current_cpu->exclusive_context_count++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
qemu_mutex_lock(&qemu_cpu_list_lock);
|
qemu_mutex_lock(&qemu_cpu_list_lock);
|
||||||
exclusive_idle();
|
exclusive_idle();
|
||||||
|
|
||||||
@ -219,13 +224,16 @@ void start_exclusive(void)
|
|||||||
*/
|
*/
|
||||||
qemu_mutex_unlock(&qemu_cpu_list_lock);
|
qemu_mutex_unlock(&qemu_cpu_list_lock);
|
||||||
|
|
||||||
current_cpu->in_exclusive_context = true;
|
current_cpu->exclusive_context_count = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finish an exclusive operation. */
|
/* Finish an exclusive operation. */
|
||||||
void end_exclusive(void)
|
void end_exclusive(void)
|
||||||
{
|
{
|
||||||
current_cpu->in_exclusive_context = false;
|
current_cpu->exclusive_context_count--;
|
||||||
|
if (current_cpu->exclusive_context_count) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
qemu_mutex_lock(&qemu_cpu_list_lock);
|
qemu_mutex_lock(&qemu_cpu_list_lock);
|
||||||
qatomic_set(&pending_cpus, 0);
|
qatomic_set(&pending_cpus, 0);
|
||||||
|
67
gdb-xml/microblaze-core.xml
Normal file
67
gdb-xml/microblaze-core.xml
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- Copyright (C) 2008 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
Copying and distribution of this file, with or without modification,
|
||||||
|
are permitted in any medium without royalty provided the copyright
|
||||||
|
notice and this notice are preserved. -->
|
||||||
|
|
||||||
|
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
|
||||||
|
<feature name="org.gnu.gdb.microblaze.core">
|
||||||
|
<reg name="r0" bitsize="32" regnum="0"/>
|
||||||
|
<reg name="r1" bitsize="32" type="data_ptr"/>
|
||||||
|
<reg name="r2" bitsize="32"/>
|
||||||
|
<reg name="r3" bitsize="32"/>
|
||||||
|
<reg name="r4" bitsize="32"/>
|
||||||
|
<reg name="r5" bitsize="32"/>
|
||||||
|
<reg name="r6" bitsize="32"/>
|
||||||
|
<reg name="r7" bitsize="32"/>
|
||||||
|
<reg name="r8" bitsize="32"/>
|
||||||
|
<reg name="r9" bitsize="32"/>
|
||||||
|
<reg name="r10" bitsize="32"/>
|
||||||
|
<reg name="r11" bitsize="32"/>
|
||||||
|
<reg name="r12" bitsize="32"/>
|
||||||
|
<reg name="r13" bitsize="32"/>
|
||||||
|
<reg name="r14" bitsize="32"/>
|
||||||
|
<reg name="r15" bitsize="32"/>
|
||||||
|
<reg name="r16" bitsize="32"/>
|
||||||
|
<reg name="r17" bitsize="32"/>
|
||||||
|
<reg name="r18" bitsize="32"/>
|
||||||
|
<reg name="r19" bitsize="32"/>
|
||||||
|
<reg name="r20" bitsize="32"/>
|
||||||
|
<reg name="r21" bitsize="32"/>
|
||||||
|
<reg name="r22" bitsize="32"/>
|
||||||
|
<reg name="r23" bitsize="32"/>
|
||||||
|
<reg name="r24" bitsize="32"/>
|
||||||
|
<reg name="r25" bitsize="32"/>
|
||||||
|
<reg name="r26" bitsize="32"/>
|
||||||
|
<reg name="r27" bitsize="32"/>
|
||||||
|
<reg name="r28" bitsize="32"/>
|
||||||
|
<reg name="r29" bitsize="32"/>
|
||||||
|
<reg name="r30" bitsize="32"/>
|
||||||
|
<reg name="r31" bitsize="32"/>
|
||||||
|
<reg name="rpc" bitsize="32" type="code_ptr"/>
|
||||||
|
<reg name="rmsr" bitsize="32"/>
|
||||||
|
<reg name="rear" bitsize="32"/>
|
||||||
|
<reg name="resr" bitsize="32"/>
|
||||||
|
<reg name="rfsr" bitsize="32"/>
|
||||||
|
<reg name="rbtr" bitsize="32"/>
|
||||||
|
<reg name="rpvr0" bitsize="32"/>
|
||||||
|
<reg name="rpvr1" bitsize="32"/>
|
||||||
|
<reg name="rpvr2" bitsize="32"/>
|
||||||
|
<reg name="rpvr3" bitsize="32"/>
|
||||||
|
<reg name="rpvr4" bitsize="32"/>
|
||||||
|
<reg name="rpvr5" bitsize="32"/>
|
||||||
|
<reg name="rpvr6" bitsize="32"/>
|
||||||
|
<reg name="rpvr7" bitsize="32"/>
|
||||||
|
<reg name="rpvr8" bitsize="32"/>
|
||||||
|
<reg name="rpvr9" bitsize="32"/>
|
||||||
|
<reg name="rpvr10" bitsize="32"/>
|
||||||
|
<reg name="rpvr11" bitsize="32"/>
|
||||||
|
<reg name="redr" bitsize="32"/>
|
||||||
|
<reg name="rpid" bitsize="32"/>
|
||||||
|
<reg name="rzpr" bitsize="32"/>
|
||||||
|
<reg name="rtlbx" bitsize="32"/>
|
||||||
|
<reg name="rtlbsx" bitsize="32"/>
|
||||||
|
<reg name="rtlblo" bitsize="32"/>
|
||||||
|
<reg name="rtlbhi" bitsize="32"/>
|
||||||
|
</feature>
|
12
gdb-xml/microblaze-stack-protect.xml
Normal file
12
gdb-xml/microblaze-stack-protect.xml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- Copyright (C) 2008 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
Copying and distribution of this file, with or without modification,
|
||||||
|
are permitted in any medium without royalty provided the copyright
|
||||||
|
notice and this notice are preserved. -->
|
||||||
|
|
||||||
|
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
|
||||||
|
<feature name="org.gnu.gdb.microblaze.stack-protect">
|
||||||
|
<reg name="rslr" bitsize="32"/>
|
||||||
|
<reg name="rshr" bitsize="32"/>
|
||||||
|
</feature>
|
@ -349,7 +349,7 @@ struct CPUState {
|
|||||||
bool unplug;
|
bool unplug;
|
||||||
bool crash_occurred;
|
bool crash_occurred;
|
||||||
bool exit_request;
|
bool exit_request;
|
||||||
bool in_exclusive_context;
|
int exclusive_context_count;
|
||||||
uint32_t cflags_next_tb;
|
uint32_t cflags_next_tb;
|
||||||
/* updates protected by BQL */
|
/* updates protected by BQL */
|
||||||
uint32_t interrupt_request;
|
uint32_t interrupt_request;
|
||||||
@ -758,7 +758,7 @@ void async_safe_run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data
|
|||||||
*/
|
*/
|
||||||
static inline bool cpu_in_exclusive_context(const CPUState *cpu)
|
static inline bool cpu_in_exclusive_context(const CPUState *cpu)
|
||||||
{
|
{
|
||||||
return cpu->in_exclusive_context;
|
return cpu->exclusive_context_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,14 +51,34 @@ typedef struct sockaddr_un {
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN64)
|
#if defined(__aarch64__)
|
||||||
/* On w64, setjmp is implemented by _setjmp which needs a second parameter.
|
/*
|
||||||
|
* On windows-arm64, setjmp is available in only one variant, and longjmp always
|
||||||
|
* does stack unwinding. This crash with generated code.
|
||||||
|
* Thus, we use another implementation of setjmp (not windows one), coming from
|
||||||
|
* mingw, which never performs stack unwinding.
|
||||||
|
*/
|
||||||
|
#undef setjmp
|
||||||
|
#undef longjmp
|
||||||
|
/*
|
||||||
|
* These functions are not declared in setjmp.h because __aarch64__ defines
|
||||||
|
* setjmp to _setjmpex instead. However, they are still defined in libmingwex.a,
|
||||||
|
* which gets linked automatically.
|
||||||
|
*/
|
||||||
|
extern int __mingw_setjmp(jmp_buf);
|
||||||
|
extern void __attribute__((noreturn)) __mingw_longjmp(jmp_buf, int);
|
||||||
|
#define setjmp(env) __mingw_setjmp(env)
|
||||||
|
#define longjmp(env, val) __mingw_longjmp(env, val)
|
||||||
|
#elif defined(_WIN64)
|
||||||
|
/*
|
||||||
|
* On windows-x64, setjmp is implemented by _setjmp which needs a second parameter.
|
||||||
* If this parameter is NULL, longjump does no stack unwinding.
|
* If this parameter is NULL, longjump does no stack unwinding.
|
||||||
* That is what we need for QEMU. Passing the value of register rsp (default)
|
* That is what we need for QEMU. Passing the value of register rsp (default)
|
||||||
* lets longjmp try a stack unwinding which will crash with generated code. */
|
* lets longjmp try a stack unwinding which will crash with generated code.
|
||||||
|
*/
|
||||||
# undef setjmp
|
# undef setjmp
|
||||||
# define setjmp(env) _setjmp(env, NULL)
|
# define setjmp(env) _setjmp(env, NULL)
|
||||||
#endif
|
#endif /* __aarch64__ */
|
||||||
/* QEMU uses sigsetjmp()/siglongjmp() as the portable way to specify
|
/* QEMU uses sigsetjmp()/siglongjmp() as the portable way to specify
|
||||||
* "longjmp and don't touch the signal masks". Since we know that the
|
* "longjmp and don't touch the signal masks". Since we know that the
|
||||||
* savemask parameter will always be zero we can safely define these
|
* savemask parameter will always be zero we can safely define these
|
||||||
|
@ -161,13 +161,15 @@ void fork_end(int child)
|
|||||||
}
|
}
|
||||||
qemu_init_cpu_list();
|
qemu_init_cpu_list();
|
||||||
gdbserver_fork(thread_cpu);
|
gdbserver_fork(thread_cpu);
|
||||||
/* qemu_init_cpu_list() takes care of reinitializing the
|
|
||||||
* exclusive state, so we don't need to end_exclusive() here.
|
|
||||||
*/
|
|
||||||
} else {
|
} else {
|
||||||
cpu_list_unlock();
|
cpu_list_unlock();
|
||||||
end_exclusive();
|
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* qemu_init_cpu_list() reinitialized the child exclusive state, but we
|
||||||
|
* also need to keep current_cpu consistent, so call end_exclusive() for
|
||||||
|
* both child and parent.
|
||||||
|
*/
|
||||||
|
end_exclusive();
|
||||||
}
|
}
|
||||||
|
|
||||||
__thread CPUState *thread_cpu;
|
__thread CPUState *thread_cpu;
|
||||||
|
@ -25,8 +25,8 @@
|
|||||||
|
|
||||||
void cpu_loop(CPUMBState *env)
|
void cpu_loop(CPUMBState *env)
|
||||||
{
|
{
|
||||||
|
int trapnr, ret, si_code, sig;
|
||||||
CPUState *cs = env_cpu(env);
|
CPUState *cs = env_cpu(env);
|
||||||
int trapnr, ret, si_code;
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
cpu_exec_start(cs);
|
cpu_exec_start(cs);
|
||||||
@ -76,6 +76,7 @@ void cpu_loop(CPUMBState *env)
|
|||||||
env->iflags &= ~(IMM_FLAG | D_FLAG);
|
env->iflags &= ~(IMM_FLAG | D_FLAG);
|
||||||
switch (env->esr & 31) {
|
switch (env->esr & 31) {
|
||||||
case ESR_EC_DIVZERO:
|
case ESR_EC_DIVZERO:
|
||||||
|
sig = TARGET_SIGFPE;
|
||||||
si_code = TARGET_FPE_INTDIV;
|
si_code = TARGET_FPE_INTDIV;
|
||||||
break;
|
break;
|
||||||
case ESR_EC_FPU:
|
case ESR_EC_FPU:
|
||||||
@ -84,6 +85,7 @@ void cpu_loop(CPUMBState *env)
|
|||||||
* if there's no recognized bit set. Possibly this
|
* if there's no recognized bit set. Possibly this
|
||||||
* implies that si_code is 0, but follow the structure.
|
* implies that si_code is 0, but follow the structure.
|
||||||
*/
|
*/
|
||||||
|
sig = TARGET_SIGFPE;
|
||||||
si_code = env->fsr;
|
si_code = env->fsr;
|
||||||
if (si_code & FSR_IO) {
|
if (si_code & FSR_IO) {
|
||||||
si_code = TARGET_FPE_FLTINV;
|
si_code = TARGET_FPE_FLTINV;
|
||||||
@ -97,13 +99,17 @@ void cpu_loop(CPUMBState *env)
|
|||||||
si_code = TARGET_FPE_FLTRES;
|
si_code = TARGET_FPE_FLTRES;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ESR_EC_PRIVINSN:
|
||||||
|
sig = SIGILL;
|
||||||
|
si_code = ILL_PRVOPC;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Unhandled hw-exception: 0x%x\n",
|
fprintf(stderr, "Unhandled hw-exception: 0x%x\n",
|
||||||
env->esr & ESR_EC_MASK);
|
env->esr & ESR_EC_MASK);
|
||||||
cpu_dump_state(cs, stderr, 0);
|
cpu_dump_state(cs, stderr, 0);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
force_sig_fault(TARGET_SIGFPE, si_code, env->pc);
|
force_sig_fault(sig, si_code, env->pc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EXCP_DEBUG:
|
case EXCP_DEBUG:
|
||||||
|
@ -248,6 +248,14 @@ void cpu_loop (CPUSPARCState *env)
|
|||||||
cpu_exec_step_atomic(cs);
|
cpu_exec_step_atomic(cs);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
/*
|
||||||
|
* Most software trap numbers vector to BAD_TRAP.
|
||||||
|
* Handle anything not explicitly matched above.
|
||||||
|
*/
|
||||||
|
if (trapnr >= TT_TRAP && trapnr <= TT_TRAP + 0x7f) {
|
||||||
|
force_sig_fault(TARGET_SIGILL, ILL_ILLTRP, env->pc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
fprintf(stderr, "Unhandled trap: 0x%x\n", trapnr);
|
fprintf(stderr, "Unhandled trap: 0x%x\n", trapnr);
|
||||||
cpu_dump_state(cs, stderr, 0);
|
cpu_dump_state(cs, stderr, 0);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
@ -6752,6 +6752,7 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
|
|||||||
cpu_clone_regs_parent(env, flags);
|
cpu_clone_regs_parent(env, flags);
|
||||||
fork_end(0);
|
fork_end(0);
|
||||||
}
|
}
|
||||||
|
g_assert(!cpu_in_exclusive_context(cpu));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
21
meson.build
21
meson.build
@ -2466,6 +2466,27 @@ if targetos == 'windows'
|
|||||||
}''', name: '_lock_file and _unlock_file'))
|
}''', name: '_lock_file and _unlock_file'))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if targetos == 'windows'
|
||||||
|
mingw_has_setjmp_longjmp = cc.links('''
|
||||||
|
#include <setjmp.h>
|
||||||
|
int main(void) {
|
||||||
|
/*
|
||||||
|
* These functions are not available in setjmp header, but may be
|
||||||
|
* available at link time, from libmingwex.a.
|
||||||
|
*/
|
||||||
|
extern int __mingw_setjmp(jmp_buf);
|
||||||
|
extern void __attribute__((noreturn)) __mingw_longjmp(jmp_buf, int);
|
||||||
|
jmp_buf env;
|
||||||
|
__mingw_setjmp(env);
|
||||||
|
__mingw_longjmp(env, 0);
|
||||||
|
}
|
||||||
|
''', name: 'mingw setjmp and longjmp')
|
||||||
|
|
||||||
|
if cpu == 'aarch64' and not mingw_has_setjmp_longjmp
|
||||||
|
error('mingw must provide setjmp/longjmp for windows-arm64')
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
########################
|
########################
|
||||||
# Target configuration #
|
# Target configuration #
|
||||||
########################
|
########################
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
#include "hw/qdev-properties.h"
|
#include "hw/qdev-properties.h"
|
||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
|
#include "exec/gdbstub.h"
|
||||||
#include "fpu/softfloat-helpers.h"
|
#include "fpu/softfloat-helpers.h"
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
@ -294,6 +295,9 @@ static void mb_cpu_initfn(Object *obj)
|
|||||||
CPUMBState *env = &cpu->env;
|
CPUMBState *env = &cpu->env;
|
||||||
|
|
||||||
cpu_set_cpustate_pointers(cpu);
|
cpu_set_cpustate_pointers(cpu);
|
||||||
|
gdb_register_coprocessor(CPU(cpu), mb_cpu_gdb_read_stack_protect,
|
||||||
|
mb_cpu_gdb_write_stack_protect, 2,
|
||||||
|
"microblaze-stack-protect.xml", 0);
|
||||||
|
|
||||||
set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
|
set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
|
||||||
|
|
||||||
@ -422,7 +426,8 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
|
|||||||
cc->sysemu_ops = &mb_sysemu_ops;
|
cc->sysemu_ops = &mb_sysemu_ops;
|
||||||
#endif
|
#endif
|
||||||
device_class_set_props(dc, mb_properties);
|
device_class_set_props(dc, mb_properties);
|
||||||
cc->gdb_num_core_regs = 32 + 27;
|
cc->gdb_num_core_regs = 32 + 25;
|
||||||
|
cc->gdb_core_xml_file = "microblaze-core.xml";
|
||||||
|
|
||||||
cc->disas_set_info = mb_disas_set_info;
|
cc->disas_set_info = mb_disas_set_info;
|
||||||
cc->tcg_ops = &mb_tcg_ops;
|
cc->tcg_ops = &mb_tcg_ops;
|
||||||
|
@ -367,6 +367,8 @@ hwaddr mb_cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr,
|
|||||||
MemTxAttrs *attrs);
|
MemTxAttrs *attrs);
|
||||||
int mb_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
|
int mb_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
|
||||||
int mb_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
|
int mb_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
|
||||||
|
int mb_cpu_gdb_read_stack_protect(CPUArchState *cpu, GByteArray *buf, int reg);
|
||||||
|
int mb_cpu_gdb_write_stack_protect(CPUArchState *cpu, uint8_t *buf, int reg);
|
||||||
|
|
||||||
static inline uint32_t mb_cpu_read_msr(const CPUMBState *env)
|
static inline uint32_t mb_cpu_read_msr(const CPUMBState *env)
|
||||||
{
|
{
|
||||||
|
@ -39,8 +39,11 @@ enum {
|
|||||||
GDB_PVR0 = 32 + 6,
|
GDB_PVR0 = 32 + 6,
|
||||||
GDB_PVR11 = 32 + 17,
|
GDB_PVR11 = 32 + 17,
|
||||||
GDB_EDR = 32 + 18,
|
GDB_EDR = 32 + 18,
|
||||||
GDB_SLR = 32 + 25,
|
};
|
||||||
GDB_SHR = 32 + 26,
|
|
||||||
|
enum {
|
||||||
|
GDB_SP_SHL,
|
||||||
|
GDB_SP_SHR,
|
||||||
};
|
};
|
||||||
|
|
||||||
int mb_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
|
int mb_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
|
||||||
@ -83,12 +86,6 @@ int mb_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
|
|||||||
case GDB_EDR:
|
case GDB_EDR:
|
||||||
val = env->edr;
|
val = env->edr;
|
||||||
break;
|
break;
|
||||||
case GDB_SLR:
|
|
||||||
val = env->slr;
|
|
||||||
break;
|
|
||||||
case GDB_SHR:
|
|
||||||
val = env->shr;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
/* Other SRegs aren't modeled, so report a value of 0 */
|
/* Other SRegs aren't modeled, so report a value of 0 */
|
||||||
val = 0;
|
val = 0;
|
||||||
@ -97,6 +94,23 @@ int mb_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
|
|||||||
return gdb_get_reg32(mem_buf, val);
|
return gdb_get_reg32(mem_buf, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mb_cpu_gdb_read_stack_protect(CPUMBState *env, GByteArray *mem_buf, int n)
|
||||||
|
{
|
||||||
|
uint32_t val;
|
||||||
|
|
||||||
|
switch (n) {
|
||||||
|
case GDB_SP_SHL:
|
||||||
|
val = env->slr;
|
||||||
|
break;
|
||||||
|
case GDB_SP_SHR:
|
||||||
|
val = env->shr;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return gdb_get_reg32(mem_buf, val);
|
||||||
|
}
|
||||||
|
|
||||||
int mb_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
|
int mb_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
|
||||||
{
|
{
|
||||||
MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
|
MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
|
||||||
@ -135,12 +149,21 @@ int mb_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
|
|||||||
case GDB_EDR:
|
case GDB_EDR:
|
||||||
env->edr = tmp;
|
env->edr = tmp;
|
||||||
break;
|
break;
|
||||||
case GDB_SLR:
|
}
|
||||||
env->slr = tmp;
|
return 4;
|
||||||
break;
|
}
|
||||||
case GDB_SHR:
|
|
||||||
env->shr = tmp;
|
int mb_cpu_gdb_write_stack_protect(CPUMBState *env, uint8_t *mem_buf, int n)
|
||||||
break;
|
{
|
||||||
|
switch (n) {
|
||||||
|
case GDB_SP_SHL:
|
||||||
|
env->slr = ldl_p(mem_buf);
|
||||||
|
break;
|
||||||
|
case GDB_SP_SHR:
|
||||||
|
env->shr = ldl_p(mem_buf);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
@ -121,8 +121,12 @@ static void sys_cache_info(int *isize, int *dsize)
|
|||||||
static bool have_coherent_icache;
|
static bool have_coherent_icache;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__aarch64__) && !defined(CONFIG_DARWIN)
|
#if defined(__aarch64__) && !defined(CONFIG_DARWIN) && !defined(CONFIG_WIN32)
|
||||||
/* Apple does not expose CTR_EL0, so we must use system interfaces. */
|
/*
|
||||||
|
* Apple does not expose CTR_EL0, so we must use system interfaces.
|
||||||
|
* Windows neither, but we use a generic implementation of flush_idcache_range
|
||||||
|
* in this case.
|
||||||
|
*/
|
||||||
static uint64_t save_ctr_el0;
|
static uint64_t save_ctr_el0;
|
||||||
static void arch_cache_info(int *isize, int *dsize)
|
static void arch_cache_info(int *isize, int *dsize)
|
||||||
{
|
{
|
||||||
@ -225,7 +229,11 @@ static void __attribute__((constructor)) init_cache_info(void)
|
|||||||
|
|
||||||
/* Caches are coherent and do not require flushing; symbol inline. */
|
/* Caches are coherent and do not require flushing; symbol inline. */
|
||||||
|
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__) && !defined(CONFIG_WIN32)
|
||||||
|
/*
|
||||||
|
* For Windows, we use generic implementation of flush_idcache_range, that
|
||||||
|
* performs a call to FlushInstructionCache, through __builtin___clear_cache.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_DARWIN
|
#ifdef CONFIG_DARWIN
|
||||||
/* Apple does not expose CTR_EL0, so we must use system interfaces. */
|
/* Apple does not expose CTR_EL0, so we must use system interfaces. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user