diff options
Diffstat (limited to 'include/exec')
| -rw-r--r-- | include/exec/cpu_ldst.h | 23 | ||||
| -rw-r--r-- | include/exec/cpu_ldst_template.h | 59 | ||||
| -rw-r--r-- | include/exec/cpu_ldst_useronly_template.h | 25 | ||||
| -rw-r--r-- | include/exec/exec-all.h | 1 | ||||
| -rw-r--r-- | include/exec/gdbstub.h | 27 | ||||
| -rw-r--r-- | include/exec/memory.h | 4 | ||||
| -rw-r--r-- | include/exec/softmmu-semi.h | 18 |
7 files changed, 126 insertions, 31 deletions
diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h index 26f479416a..b573df53b0 100644 --- a/include/exec/cpu_ldst.h +++ b/include/exec/cpu_ldst.h @@ -113,25 +113,6 @@ /* The memory helpers for tcg-generated code need tcg_target_long etc. */ #include "tcg.h" -uint8_t helper_ldb_mmu(CPUArchState *env, target_ulong addr, int mmu_idx); -uint16_t helper_ldw_mmu(CPUArchState *env, target_ulong addr, int mmu_idx); -uint32_t helper_ldl_mmu(CPUArchState *env, target_ulong addr, int mmu_idx); -uint64_t helper_ldq_mmu(CPUArchState *env, target_ulong addr, int mmu_idx); - -void helper_stb_mmu(CPUArchState *env, target_ulong addr, - uint8_t val, int mmu_idx); -void helper_stw_mmu(CPUArchState *env, target_ulong addr, - uint16_t val, int mmu_idx); -void helper_stl_mmu(CPUArchState *env, target_ulong addr, - uint32_t val, int mmu_idx); -void helper_stq_mmu(CPUArchState *env, target_ulong addr, - uint64_t val, int mmu_idx); - -uint8_t helper_ldb_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx); -uint16_t helper_ldw_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx); -uint32_t helper_ldl_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx); -uint64_t helper_ldq_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx); - #ifdef MMU_MODE0_SUFFIX #define CPU_MMU_INDEX 0 #define MEMSUFFIX MMU_MODE0_SUFFIX @@ -363,7 +344,7 @@ uint64_t helper_ldq_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx); #endif /* (NB_MMU_MODES > 12) */ /* these access are slower, they must be as rare as possible */ -#define CPU_MMU_INDEX (cpu_mmu_index(env)) +#define CPU_MMU_INDEX (cpu_mmu_index(env, false)) #define MEMSUFFIX _data #define DATA_SIZE 1 #include "exec/cpu_ldst_template.h" @@ -379,7 +360,7 @@ uint64_t helper_ldq_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx); #undef CPU_MMU_INDEX #undef MEMSUFFIX -#define CPU_MMU_INDEX (cpu_mmu_index(env)) +#define CPU_MMU_INDEX (cpu_mmu_index(env, true)) #define MEMSUFFIX _code #define SOFTMMU_CODE_ACCESS diff --git a/include/exec/cpu_ldst_template.h b/include/exec/cpu_ldst_template.h index 95ab7504e2..3091c00030 100644 --- a/include/exec/cpu_ldst_template.h +++ b/include/exec/cpu_ldst_template.h @@ -27,20 +27,24 @@ #define SUFFIX q #define USUFFIX q #define DATA_TYPE uint64_t +#define SHIFT 3 #elif DATA_SIZE == 4 #define SUFFIX l #define USUFFIX l #define DATA_TYPE uint32_t +#define SHIFT 2 #elif DATA_SIZE == 2 #define SUFFIX w #define USUFFIX uw #define DATA_TYPE uint16_t #define DATA_STYPE int16_t +#define SHIFT 1 #elif DATA_SIZE == 1 #define SUFFIX b #define USUFFIX ub #define DATA_TYPE uint8_t #define DATA_STYPE int8_t +#define SHIFT 0 #else #error unsupported data size #endif @@ -54,27 +58,36 @@ #ifdef SOFTMMU_CODE_ACCESS #define ADDR_READ addr_code #define MMUSUFFIX _cmmu +#define URETSUFFIX SUFFIX +#define SRETSUFFIX SUFFIX #else #define ADDR_READ addr_read #define MMUSUFFIX _mmu +#define URETSUFFIX USUFFIX +#define SRETSUFFIX glue(s, SUFFIX) #endif /* generic load/store macros */ static inline RES_TYPE -glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr) +glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env, + target_ulong ptr, + uintptr_t retaddr) { int page_index; RES_TYPE res; target_ulong addr; int mmu_idx; + TCGMemOpIdx oi; addr = ptr; page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); mmu_idx = CPU_MMU_INDEX; if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ != (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) { - res = glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(env, addr, mmu_idx); + oi = make_memop_idx(SHIFT, mmu_idx); + res = glue(glue(helper_ret_ld, URETSUFFIX), MMUSUFFIX)(env, addr, + oi, retaddr); } else { uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend; res = glue(glue(ld, USUFFIX), _p)((uint8_t *)hostaddr); @@ -82,27 +95,43 @@ glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr) return res; } +static inline RES_TYPE +glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr) +{ + return glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(env, ptr, 0); +} + #if DATA_SIZE <= 2 static inline int -glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr) +glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env, + target_ulong ptr, + uintptr_t retaddr) { int res, page_index; target_ulong addr; int mmu_idx; + TCGMemOpIdx oi; addr = ptr; page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); mmu_idx = CPU_MMU_INDEX; if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ != (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) { - res = (DATA_STYPE)glue(glue(helper_ld, SUFFIX), - MMUSUFFIX)(env, addr, mmu_idx); + oi = make_memop_idx(SHIFT, mmu_idx); + res = (DATA_STYPE)glue(glue(helper_ret_ld, SRETSUFFIX), + MMUSUFFIX)(env, addr, oi, retaddr); } else { uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend; res = glue(glue(lds, SUFFIX), _p)((uint8_t *)hostaddr); } return res; } + +static inline int +glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr) +{ + return glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(env, ptr, 0); +} #endif #ifndef SOFTMMU_CODE_ACCESS @@ -110,25 +139,36 @@ glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr) /* generic store macro */ static inline void -glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr, - RES_TYPE v) +glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env, + target_ulong ptr, + RES_TYPE v, uintptr_t retaddr) { int page_index; target_ulong addr; int mmu_idx; + TCGMemOpIdx oi; addr = ptr; page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); mmu_idx = CPU_MMU_INDEX; if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write != (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) { - glue(glue(helper_st, SUFFIX), MMUSUFFIX)(env, addr, v, mmu_idx); + oi = make_memop_idx(SHIFT, mmu_idx); + glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(env, addr, v, oi, + retaddr); } else { uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend; glue(glue(st, SUFFIX), _p)((uint8_t *)hostaddr, v); } } +static inline void +glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr, + RES_TYPE v) +{ + glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(env, ptr, v, 0); +} + #endif /* !SOFTMMU_CODE_ACCESS */ #undef RES_TYPE @@ -139,3 +179,6 @@ glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr, #undef DATA_SIZE #undef MMUSUFFIX #undef ADDR_READ +#undef URETSUFFIX +#undef SRETSUFFIX +#undef SHIFT diff --git a/include/exec/cpu_ldst_useronly_template.h b/include/exec/cpu_ldst_useronly_template.h index b3b865fae8..040b147437 100644 --- a/include/exec/cpu_ldst_useronly_template.h +++ b/include/exec/cpu_ldst_useronly_template.h @@ -56,12 +56,28 @@ glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr) return glue(glue(ld, USUFFIX), _p)(g2h(ptr)); } +static inline RES_TYPE +glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env, + target_ulong ptr, + uintptr_t retaddr) +{ + return glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(env, ptr); +} + #if DATA_SIZE <= 2 static inline int glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr) { return glue(glue(lds, SUFFIX), _p)(g2h(ptr)); } + +static inline int +glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env, + target_ulong ptr, + uintptr_t retaddr) +{ + return glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(env, ptr); +} #endif #ifndef CODE_ACCESS @@ -71,6 +87,15 @@ glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr, { glue(glue(st, SUFFIX), _p)(g2h(ptr), v); } + +static inline void +glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env, + target_ulong ptr, + RES_TYPE v, + uintptr_t retaddr) +{ + glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(env, ptr, v); +} #endif #undef RES_TYPE diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 05a5d5c53b..72d4012ed9 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -90,6 +90,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu, int cflags); void cpu_exec_init(CPUState *cpu, Error **errp); void QEMU_NORETURN cpu_loop_exit(CPUState *cpu); +void QEMU_NORETURN cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc); #if !defined(CONFIG_USER_ONLY) bool qemu_in_vcpu_thread(void); diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h index 05f57c2432..d9e8cf7715 100644 --- a/include/exec/gdbstub.h +++ b/include/exec/gdbstub.h @@ -14,7 +14,34 @@ typedef void (*gdb_syscall_complete_cb)(CPUState *cpu, target_ulong ret, target_ulong err); +/** + * gdb_do_syscall: + * @cb: function to call when the system call has completed + * @fmt: gdb syscall format string + * ...: list of arguments to interpolate into @fmt + * + * Send a GDB syscall request. This function will return immediately; + * the callback function will be called later when the remote system + * call has completed. + * + * @fmt should be in the 'call-id,parameter,parameter...' format documented + * for the F request packet in the GDB remote protocol. A limited set of + * printf-style format specifiers is supported: + * %x - target_ulong argument printed in hex + * %lx - 64-bit argument printed in hex + * %s - string pointer (target_ulong) and length (int) pair + */ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...); +/** + * gdb_do_syscallv: + * @cb: function to call when the system call has completed + * @fmt: gdb syscall format string + * @va: arguments to interpolate into @fmt + * + * As gdb_do_syscall, but taking a va_list rather than a variable + * argument list. + */ +void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char *fmt, va_list va); int use_gdb_syscalls(void); void gdb_set_stop_cpu(CPUState *cpu); void gdb_exit(CPUArchState *, int); diff --git a/include/exec/memory.h b/include/exec/memory.h index b18b351e33..5baaf48234 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -324,7 +324,7 @@ void memory_region_unref(MemoryRegion *mr); * @owner: the object that tracks the region's reference count * @ops: a structure containing read and write callbacks to be used when * I/O is performed on the region. - * @opaque: passed to to the read and write callbacks of the @ops structure. + * @opaque: passed to the read and write callbacks of the @ops structure. * @name: used for debugging; not visible to the user or ABI * @size: size of the region. */ @@ -1146,7 +1146,7 @@ MemTxResult memory_region_dispatch_write(MemoryRegion *mr, * address_space_init: initializes an address space * * @as: an uninitialized #AddressSpace - * @root: a #MemoryRegion that routes addesses for the address space + * @root: a #MemoryRegion that routes addresses for the address space * @name: an address space name. The name is only used for debugging * output. */ diff --git a/include/exec/softmmu-semi.h b/include/exec/softmmu-semi.h index 1819cc2498..3a58c3f087 100644 --- a/include/exec/softmmu-semi.h +++ b/include/exec/softmmu-semi.h @@ -9,6 +9,14 @@ #ifndef SOFTMMU_SEMI_H #define SOFTMMU_SEMI_H 1 +static inline uint64_t softmmu_tget64(CPUArchState *env, target_ulong addr) +{ + uint64_t val; + + cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)&val, 8, 0); + return tswap64(val); +} + static inline uint32_t softmmu_tget32(CPUArchState *env, target_ulong addr) { uint32_t val; @@ -16,6 +24,7 @@ static inline uint32_t softmmu_tget32(CPUArchState *env, target_ulong addr) cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)&val, 4, 0); return tswap32(val); } + static inline uint32_t softmmu_tget8(CPUArchState *env, target_ulong addr) { uint8_t val; @@ -24,16 +33,25 @@ static inline uint32_t softmmu_tget8(CPUArchState *env, target_ulong addr) return val; } +#define get_user_u64(arg, p) ({ arg = softmmu_tget64(env, p); 0; }) #define get_user_u32(arg, p) ({ arg = softmmu_tget32(env, p) ; 0; }) #define get_user_u8(arg, p) ({ arg = softmmu_tget8(env, p) ; 0; }) #define get_user_ual(arg, p) get_user_u32(arg, p) +static inline void softmmu_tput64(CPUArchState *env, + target_ulong addr, uint64_t val) +{ + val = tswap64(val); + cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)&val, 8, 1); +} + static inline void softmmu_tput32(CPUArchState *env, target_ulong addr, uint32_t val) { val = tswap32(val); cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)&val, 4, 1); } +#define put_user_u64(arg, p) ({ softmmu_tput64(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) |