diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2017-01-25 10:54:11 -0800 |
---|---|---|
committer | Max Filippov <jcmvbkbc@gmail.com> | 2018-03-16 09:40:34 -0700 |
commit | ba7651fba54199e5dedbbd08157687291b9dbae3 (patch) | |
tree | f03b970e3cfdfde9040ff14c59dc0bf3acfb6fe3 /target | |
parent | bf9c3a5a96dfabcdcb7964110866bb9bc06a43c1 (diff) |
target/xtensa: add linux-user support
Import list of syscalls from the kernel source. Conditionalize code/data
that is only used with softmmu. Implement exception handlers. Implement
signal hander (only the core registers for now, no coprocessors or TIE).
Cc: Riku Voipio <riku.voipio@iki.fi>
Cc: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Diffstat (limited to 'target')
-rw-r--r-- | target/xtensa/Makefile.objs | 3 | ||||
-rw-r--r-- | target/xtensa/cpu.c | 26 | ||||
-rw-r--r-- | target/xtensa/cpu.h | 56 | ||||
-rw-r--r-- | target/xtensa/helper.c | 31 | ||||
-rw-r--r-- | target/xtensa/helper.h | 4 | ||||
-rw-r--r-- | target/xtensa/op_helper.c | 50 | ||||
-rw-r--r-- | target/xtensa/translate.c | 43 |
7 files changed, 173 insertions, 40 deletions
diff --git a/target/xtensa/Makefile.objs b/target/xtensa/Makefile.objs index e15851521f..2fae785cb2 100644 --- a/target/xtensa/Makefile.objs +++ b/target/xtensa/Makefile.objs @@ -1,10 +1,9 @@ -obj-y += xtensa-semi.o obj-y += core-dc232b.o obj-y += core-dc233c.o obj-y += core-de212.o obj-y += core-fsf.o obj-y += core-sample_controller.o -obj-$(CONFIG_SOFTMMU) += monitor.o +obj-$(CONFIG_SOFTMMU) += monitor.o xtensa-semi.o obj-y += xtensa-isa.o obj-y += translate.o op_helper.o helper.o cpu.o obj-y += gdbstub.o diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c index 4573388a45..2b5b537222 100644 --- a/target/xtensa/cpu.c +++ b/target/xtensa/cpu.c @@ -45,9 +45,13 @@ static void xtensa_cpu_set_pc(CPUState *cs, vaddr value) static bool xtensa_cpu_has_work(CPUState *cs) { +#ifndef CONFIG_USER_ONLY XtensaCPU *cpu = XTENSA_CPU(cs); return !cpu->env.runstall && cpu->env.pending_irq_level; +#else + return true; +#endif } /* CPUClass::reset() */ @@ -62,8 +66,16 @@ static void xtensa_cpu_reset(CPUState *s) env->exception_taken = 0; env->pc = env->config->exception_vector[EXC_RESET0 + env->static_vectors]; env->sregs[LITBASE] &= ~1; +#ifndef CONFIG_USER_ONLY env->sregs[PS] = xtensa_option_enabled(env->config, XTENSA_OPTION_INTERRUPT) ? 0x1f : 0x10; + env->pending_irq_level = 0; +#else + env->sregs[PS] = + (xtensa_option_enabled(env->config, + XTENSA_OPTION_WINDOWED_REGISTER) ? PS_WOE : 0) | + PS_UM | (3 << PS_RING_SHIFT); +#endif env->sregs[VECBASE] = env->config->vecbase; env->sregs[IBREAKENABLE] = 0; env->sregs[MEMCTL] = MEMCTL_IL0EN & env->config->memctl_mask; @@ -73,9 +85,10 @@ static void xtensa_cpu_reset(CPUState *s) env->sregs[CONFIGID0] = env->config->configid[0]; env->sregs[CONFIGID1] = env->config->configid[1]; - env->pending_irq_level = 0; +#ifndef CONFIG_USER_ONLY reset_mmu(env); s->halted = env->runstall; +#endif } static ObjectClass *xtensa_cpu_class_by_name(const char *cpu_model) @@ -104,11 +117,12 @@ static void xtensa_cpu_disas_set_info(CPUState *cs, disassemble_info *info) static void xtensa_cpu_realizefn(DeviceState *dev, Error **errp) { CPUState *cs = CPU(dev); - XtensaCPU *cpu = XTENSA_CPU(dev); XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(dev); Error *local_err = NULL; - xtensa_irq_init(&cpu->env); +#ifndef CONFIG_USER_ONLY + xtensa_irq_init(&XTENSA_CPU(dev)->env); +#endif cpu_exec_realizefn(cs, &local_err); if (local_err != NULL) { @@ -133,11 +147,13 @@ static void xtensa_cpu_initfn(Object *obj) cs->env_ptr = env; env->config = xcc->config; +#ifndef CONFIG_USER_ONLY env->address_space_er = g_malloc(sizeof(*env->address_space_er)); env->system_er = g_malloc(sizeof(*env->system_er)); memory_region_init_io(env->system_er, NULL, NULL, env, "er", UINT64_C(0x100000000)); address_space_init(env->address_space_er, env->system_er, "ER"); +#endif } static const VMStateDescription vmstate_xtensa_cpu = { @@ -166,7 +182,9 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data) cc->gdb_read_register = xtensa_cpu_gdb_read_register; cc->gdb_write_register = xtensa_cpu_gdb_write_register; cc->gdb_stop_before_watchpoint = true; -#ifndef CONFIG_USER_ONLY +#ifdef CONFIG_USER_ONLY + cc->handle_mmu_fault = xtensa_cpu_handle_mmu_fault; +#else cc->do_unaligned_access = xtensa_cpu_do_unaligned_access; cc->get_phys_page_debug = xtensa_cpu_get_phys_page_debug; cc->do_unassigned_access = xtensa_cpu_do_unassigned_access; diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h index d9d3b33a70..957f0fd59a 100644 --- a/target/xtensa/cpu.h +++ b/target/xtensa/cpu.h @@ -44,7 +44,11 @@ #define NB_MMU_MODES 4 #define TARGET_PHYS_ADDR_SPACE_BITS 32 +#ifdef CONFIG_USER_ONLY +#define TARGET_VIRT_ADDR_SPACE_BITS 30 +#else #define TARGET_VIRT_ADDR_SPACE_BITS 32 +#endif #define TARGET_PAGE_BITS 12 enum { @@ -176,6 +180,7 @@ enum { #define PS_OWB 0xf00 #define PS_OWB_SHIFT 8 +#define PS_OWB_LEN 4 #define PS_CALLINC 0x30000 #define PS_CALLINC_SHIFT 16 @@ -438,6 +443,7 @@ typedef struct CPUXtensaState { } fregs[16]; float_status fp_status; +#ifndef CONFIG_USER_ONLY xtensa_tlb_entry itlb[7][MAX_TLB_WAY_SIZE]; xtensa_tlb_entry dtlb[10][MAX_TLB_WAY_SIZE]; unsigned autorefill_idx; @@ -450,6 +456,7 @@ typedef struct CPUXtensaState { uint64_t time_base; uint64_t ccount_time; uint32_t ccount_base; +#endif int exception_taken; int yield_needed; @@ -484,6 +491,9 @@ static inline XtensaCPU *xtensa_env_get_cpu(const CPUXtensaState *env) #define ENV_OFFSET offsetof(XtensaCPU, env) + +int xtensa_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, int size, + int mmu_idx); void xtensa_cpu_do_interrupt(CPUState *cpu); bool xtensa_cpu_exec_interrupt(CPUState *cpu, int interrupt_request); void xtensa_cpu_do_unassigned_access(CPUState *cpu, hwaddr addr, @@ -531,26 +541,9 @@ int cpu_xtensa_signal_handler(int host_signum, void *pinfo, void *puc); void xtensa_cpu_list(FILE *f, fprintf_function cpu_fprintf); void xtensa_sync_window_from_phys(CPUXtensaState *env); void xtensa_sync_phys_from_window(CPUXtensaState *env); -uint32_t xtensa_tlb_get_addr_mask(const CPUXtensaState *env, bool dtlb, uint32_t way); -void split_tlb_entry_spec_way(const CPUXtensaState *env, uint32_t v, bool dtlb, - uint32_t *vpn, uint32_t wi, uint32_t *ei); -int xtensa_tlb_lookup(const CPUXtensaState *env, uint32_t addr, bool dtlb, - uint32_t *pwi, uint32_t *pei, uint8_t *pring); -void xtensa_tlb_set_entry_mmu(const CPUXtensaState *env, - xtensa_tlb_entry *entry, bool dtlb, - unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte); -void xtensa_tlb_set_entry(CPUXtensaState *env, bool dtlb, - unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte); -int xtensa_get_physical_addr(CPUXtensaState *env, bool update_tlb, - uint32_t vaddr, int is_write, int mmu_idx, - uint32_t *paddr, uint32_t *page_size, unsigned *access); -void reset_mmu(CPUXtensaState *env); -void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUXtensaState *env); +void xtensa_rotate_window(CPUXtensaState *env, uint32_t delta); +void xtensa_restore_owb(CPUXtensaState *env); void debug_exception_env(CPUXtensaState *new_env, uint32_t cause); -static inline MemoryRegion *xtensa_get_er_region(CPUXtensaState *env) -{ - return env->system_er; -} static inline void xtensa_select_static_vectors(CPUXtensaState *env, unsigned n) @@ -604,6 +597,29 @@ static inline int xtensa_get_cring(const CPUXtensaState *env) } } +#ifndef CONFIG_USER_ONLY +uint32_t xtensa_tlb_get_addr_mask(const CPUXtensaState *env, + bool dtlb, uint32_t way); +void split_tlb_entry_spec_way(const CPUXtensaState *env, uint32_t v, bool dtlb, + uint32_t *vpn, uint32_t wi, uint32_t *ei); +int xtensa_tlb_lookup(const CPUXtensaState *env, uint32_t addr, bool dtlb, + uint32_t *pwi, uint32_t *pei, uint8_t *pring); +void xtensa_tlb_set_entry_mmu(const CPUXtensaState *env, + xtensa_tlb_entry *entry, bool dtlb, + unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte); +void xtensa_tlb_set_entry(CPUXtensaState *env, bool dtlb, + unsigned wi, unsigned ei, uint32_t vpn, uint32_t pte); +int xtensa_get_physical_addr(CPUXtensaState *env, bool update_tlb, + uint32_t vaddr, int is_write, int mmu_idx, + uint32_t *paddr, uint32_t *page_size, unsigned *access); +void reset_mmu(CPUXtensaState *env); +void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUXtensaState *env); + +static inline MemoryRegion *xtensa_get_er_region(CPUXtensaState *env) +{ + return env->system_er; +} + static inline xtensa_tlb_entry *xtensa_tlb_get_entry(CPUXtensaState *env, bool dtlb, unsigned wi, unsigned ei) { @@ -611,6 +627,7 @@ static inline xtensa_tlb_entry *xtensa_tlb_get_entry(CPUXtensaState *env, env->dtlb[wi] + ei : env->itlb[wi] + ei; } +#endif static inline uint32_t xtensa_replicate_windowstart(CPUXtensaState *env) { @@ -623,6 +640,7 @@ static inline uint32_t xtensa_replicate_windowstart(CPUXtensaState *env) #define MMU_MODE1_SUFFIX _ring1 #define MMU_MODE2_SUFFIX _ring2 #define MMU_MODE3_SUFFIX _ring3 +#define MMU_USER_IDX 3 static inline int cpu_mmu_index(CPUXtensaState *env, bool ifetch) { diff --git a/target/xtensa/helper.c b/target/xtensa/helper.c index 34885038d5..34844eead3 100644 --- a/target/xtensa/helper.c +++ b/target/xtensa/helper.c @@ -173,6 +173,7 @@ void xtensa_cpu_list(FILE *f, fprintf_function cpu_fprintf) hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { +#ifndef CONFIG_USER_ONLY XtensaCPU *cpu = XTENSA_CPU(cs); uint32_t paddr; uint32_t page_size; @@ -187,8 +188,13 @@ hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) return paddr; } return ~0; +#else + return addr; +#endif } +#ifndef CONFIG_USER_ONLY + static uint32_t relocated_vector(CPUXtensaState *env, uint32_t vector) { if (xtensa_option_enabled(env->config, @@ -298,6 +304,11 @@ void xtensa_cpu_do_interrupt(CPUState *cs) } check_interrupts(env); } +#else +void xtensa_cpu_do_interrupt(CPUState *cs) +{ +} +#endif bool xtensa_cpu_exec_interrupt(CPUState *cs, int interrupt_request) { @@ -309,6 +320,25 @@ bool xtensa_cpu_exec_interrupt(CPUState *cs, int interrupt_request) return false; } +#ifdef CONFIG_USER_ONLY + +int xtensa_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int size, int rw, + int mmu_idx) +{ + XtensaCPU *cpu = XTENSA_CPU(cs); + CPUXtensaState *env = &cpu->env; + + qemu_log_mask(CPU_LOG_INT, + "%s: rw = %d, address = 0x%08" VADDR_PRIx ", size = %d\n", + __func__, rw, address, size); + env->sregs[EXCVADDR] = address; + env->sregs[EXCCAUSE] = rw ? STORE_PROHIBITED_CAUSE : LOAD_PROHIBITED_CAUSE; + cs->exception_index = EXC_USER; + return 1; +} + +#else + static void reset_tlb_mmu_all_ways(CPUXtensaState *env, const xtensa_tlb *tlb, xtensa_tlb_entry entry[][MAX_TLB_WAY_SIZE]) { @@ -769,3 +799,4 @@ void xtensa_runstall(CPUXtensaState *env, bool runstall) cpu_reset_interrupt(cpu, CPU_INTERRUPT_HALT); } } +#endif diff --git a/target/xtensa/helper.h b/target/xtensa/helper.h index cc751c98fb..73444ae02c 100644 --- a/target/xtensa/helper.h +++ b/target/xtensa/helper.h @@ -12,9 +12,12 @@ DEF_HELPER_1(restore_owb, void, env) DEF_HELPER_2(movsp, void, env, i32) DEF_HELPER_2(wsr_lbeg, void, env, i32) DEF_HELPER_2(wsr_lend, void, env, i32) +#ifndef CONFIG_USER_ONLY DEF_HELPER_1(simcall, void, env) +#endif DEF_HELPER_1(dump_state, void, env) +#ifndef CONFIG_USER_ONLY DEF_HELPER_3(waiti, void, env, i32, i32) DEF_HELPER_1(update_ccount, void, env) DEF_HELPER_2(wsr_ccount, void, env, i32) @@ -35,6 +38,7 @@ DEF_HELPER_2(wsr_ibreakenable, void, env, i32) DEF_HELPER_3(wsr_ibreaka, void, env, i32, i32) DEF_HELPER_3(wsr_dbreaka, void, env, i32, i32) DEF_HELPER_3(wsr_dbreakc, void, env, i32, i32) +#endif DEF_HELPER_2(wur_fcr, void, env, i32) DEF_HELPER_FLAGS_1(abs_s, TCG_CALL_NO_RWG_SE, f32, f32) diff --git a/target/xtensa/op_helper.c b/target/xtensa/op_helper.c index 7486b99799..d401105d09 100644 --- a/target/xtensa/op_helper.c +++ b/target/xtensa/op_helper.c @@ -36,6 +36,13 @@ #include "qemu/timer.h" #include "fpu/softfloat.h" +#ifdef CONFIG_USER_ONLY +/* tb_invalidate_phys_range */ +#include "accel/tcg/translate-all.h" +#endif + +#ifndef CONFIG_USER_ONLY + void xtensa_cpu_do_unaligned_access(CPUState *cs, vaddr addr, MMUAccessType access_type, int mmu_idx, uintptr_t retaddr) @@ -102,6 +109,17 @@ static void tb_invalidate_virtual_addr(CPUXtensaState *env, uint32_t vaddr) } } +#else + +static void tb_invalidate_virtual_addr(CPUXtensaState *env, uint32_t vaddr) +{ + mmap_lock(); + tb_invalidate_phys_range(vaddr, vaddr + 1); + mmap_unlock(); +} + +#endif + void HELPER(exception)(CPUXtensaState *env, uint32_t excp) { CPUState *cs = CPU(xtensa_env_get_cpu(env)); @@ -219,21 +237,21 @@ void xtensa_sync_phys_from_window(CPUXtensaState *env) copy_phys_from_window(env, env->sregs[WINDOW_BASE] * 4, 0, 16); } -static void rotate_window_abs(CPUXtensaState *env, uint32_t position) +static void xtensa_rotate_window_abs(CPUXtensaState *env, uint32_t position) { xtensa_sync_phys_from_window(env); env->sregs[WINDOW_BASE] = windowbase_bound(position, env); xtensa_sync_window_from_phys(env); } -static void rotate_window(CPUXtensaState *env, uint32_t delta) +void xtensa_rotate_window(CPUXtensaState *env, uint32_t delta) { - rotate_window_abs(env, env->sregs[WINDOW_BASE] + delta); + xtensa_rotate_window_abs(env, env->sregs[WINDOW_BASE] + delta); } void HELPER(wsr_windowbase)(CPUXtensaState *env, uint32_t v) { - rotate_window_abs(env, v); + xtensa_rotate_window_abs(env, v); } void HELPER(entry)(CPUXtensaState *env, uint32_t pc, uint32_t s, uint32_t imm) @@ -251,7 +269,7 @@ void HELPER(entry)(CPUXtensaState *env, uint32_t pc, uint32_t s, uint32_t imm) HELPER(window_check)(env, pc, callinc); } env->regs[(callinc << 2) | (s & 3)] = env->regs[s] - imm; - rotate_window(env, callinc); + xtensa_rotate_window(env, callinc); env->sregs[WINDOW_START] |= windowstart_bit(env->sregs[WINDOW_BASE], env); } @@ -266,7 +284,7 @@ void HELPER(window_check)(CPUXtensaState *env, uint32_t pc, uint32_t w) assert(n <= w); - rotate_window(env, n); + xtensa_rotate_window(env, n); env->sregs[PS] = (env->sregs[PS] & ~PS_OWB) | (windowbase << PS_OWB_SHIFT) | PS_EXCM; env->sregs[EPC1] = env->pc = pc; @@ -311,7 +329,7 @@ uint32_t HELPER(retw)(CPUXtensaState *env, uint32_t pc) ret_pc = (pc & 0xc0000000) | (env->regs[0] & 0x3fffffff); - rotate_window(env, -n); + xtensa_rotate_window(env, -n); if (windowstart & windowstart_bit(env->sregs[WINDOW_BASE], env)) { env->sregs[WINDOW_START] &= ~windowstart_bit(owb, env); } else { @@ -334,12 +352,17 @@ uint32_t HELPER(retw)(CPUXtensaState *env, uint32_t pc) void HELPER(rotw)(CPUXtensaState *env, uint32_t imm4) { - rotate_window(env, imm4); + xtensa_rotate_window(env, imm4); +} + +void xtensa_restore_owb(CPUXtensaState *env) +{ + xtensa_rotate_window_abs(env, (env->sregs[PS] & PS_OWB) >> PS_OWB_SHIFT); } void HELPER(restore_owb)(CPUXtensaState *env) { - rotate_window_abs(env, (env->sregs[PS] & PS_OWB) >> PS_OWB_SHIFT); + xtensa_restore_owb(env); } void HELPER(movsp)(CPUXtensaState *env, uint32_t pc) @@ -376,6 +399,8 @@ void HELPER(dump_state)(CPUXtensaState *env) cpu_dump_state(CPU(cpu), stderr, fprintf, 0); } +#ifndef CONFIG_USER_ONLY + void HELPER(waiti)(CPUXtensaState *env, uint32_t pc, uint32_t intlevel) { CPUState *cpu; @@ -888,6 +913,7 @@ void HELPER(wsr_dbreakc)(CPUXtensaState *env, uint32_t i, uint32_t v) } env->sregs[DBREAKC + i] = v; } +#endif void HELPER(wur_fcr)(CPUXtensaState *env, uint32_t v) { @@ -1025,12 +1051,18 @@ void HELPER(ule_s)(CPUXtensaState *env, uint32_t br, float32 a, float32 b) uint32_t HELPER(rer)(CPUXtensaState *env, uint32_t addr) { +#ifndef CONFIG_USER_ONLY return address_space_ldl(env->address_space_er, addr, MEMTXATTRS_UNSPECIFIED, NULL); +#else + return 0; +#endif } void HELPER(wer)(CPUXtensaState *env, uint32_t data, uint32_t addr) { +#ifndef CONFIG_USER_ONLY address_space_stl(env->address_space_er, addr, data, MEMTXATTRS_UNSPECIFIED, NULL); +#endif } diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c index c06d30d179..4f6d03059f 100644 --- a/target/xtensa/translate.c +++ b/target/xtensa/translate.c @@ -345,12 +345,14 @@ static void gen_debug_exception(DisasContext *dc, uint32_t cause) static bool gen_check_privilege(DisasContext *dc) { - if (dc->cring) { - gen_exception_cause(dc, PRIVILEGED_CAUSE); - dc->is_jmp = DISAS_UPDATE; - return false; +#ifndef CONFIG_USER_ONLY + if (!dc->cring) { + return true; } - return true; +#endif + gen_exception_cause(dc, PRIVILEGED_CAUSE); + dc->is_jmp = DISAS_UPDATE; + return false; } static bool gen_check_cpenable(DisasContext *dc, unsigned cp) @@ -498,6 +500,7 @@ static bool gen_check_sr(DisasContext *dc, uint32_t sr, unsigned access) return true; } +#ifndef CONFIG_USER_ONLY static bool gen_rsr_ccount(DisasContext *dc, TCGv_i32 d, uint32_t sr) { if (tb_cflags(dc->tb) & CF_USE_ICOUNT) { @@ -519,14 +522,17 @@ static bool gen_rsr_ptevaddr(DisasContext *dc, TCGv_i32 d, uint32_t sr) tcg_gen_andi_i32(d, d, 0xfffffffc); return false; } +#endif static bool gen_rsr(DisasContext *dc, TCGv_i32 d, uint32_t sr) { static bool (* const rsr_handler[256])(DisasContext *dc, TCGv_i32 d, uint32_t sr) = { +#ifndef CONFIG_USER_ONLY [CCOUNT] = gen_rsr_ccount, [INTSET] = gen_rsr_ccount, [PTEVADDR] = gen_rsr_ptevaddr, +#endif }; if (rsr_handler[sr]) { @@ -582,6 +588,7 @@ static bool gen_wsr_acchi(DisasContext *dc, uint32_t sr, TCGv_i32 s) return false; } +#ifndef CONFIG_USER_ONLY static bool gen_wsr_windowbase(DisasContext *dc, uint32_t sr, TCGv_i32 v) { gen_helper_wsr_windowbase(cpu_env, v); @@ -797,6 +804,11 @@ static bool gen_wsr_ccompare(DisasContext *dc, uint32_t sr, TCGv_i32 v) } return ret; } +#else +static void gen_check_interrupts(DisasContext *dc) +{ +} +#endif static bool gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s) { @@ -808,6 +820,7 @@ static bool gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s) [BR] = gen_wsr_br, [LITBASE] = gen_wsr_litbase, [ACCHI] = gen_wsr_acchi, +#ifndef CONFIG_USER_ONLY [WINDOW_BASE] = gen_wsr_windowbase, [WINDOW_START] = gen_wsr_windowstart, [PTEVADDR] = gen_wsr_ptevaddr, @@ -834,6 +847,7 @@ static bool gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s) [CCOMPARE] = gen_wsr_ccompare, [CCOMPARE + 1] = gen_wsr_ccompare, [CCOMPARE + 2] = gen_wsr_ccompare, +#endif }; if (wsr_handler[sr]) { @@ -878,6 +892,7 @@ static void gen_load_store_alignment(DisasContext *dc, int shift, } } +#ifndef CONFIG_USER_ONLY static void gen_waiti(DisasContext *dc, uint32_t imm4) { TCGv_i32 pc = tcg_const_i32(dc->next_pc); @@ -894,6 +909,7 @@ static void gen_waiti(DisasContext *dc, uint32_t imm4) tcg_temp_free(intlevel); gen_jumpi_check_loop_end(dc, 0); } +#endif static bool gen_window_check1(DisasContext *dc, unsigned r1) { @@ -1596,12 +1612,14 @@ static void translate_icache(DisasContext *dc, const uint32_t arg[], { if ((!par[0] || gen_check_privilege(dc)) && gen_window_check1(dc, arg[0]) && par[1]) { +#ifndef CONFIG_USER_ONLY TCGv_i32 addr = tcg_temp_new_i32(); tcg_gen_movi_i32(cpu_pc, dc->pc); tcg_gen_addi_i32(addr, cpu_R[arg[0]], arg[1]); gen_helper_itlb_hit_test(cpu_env, addr); tcg_temp_free(addr); +#endif } } @@ -1610,12 +1628,14 @@ static void translate_itlb(DisasContext *dc, const uint32_t arg[], { if (gen_check_privilege(dc) && gen_window_check1(dc, arg[0])) { +#ifndef CONFIG_USER_ONLY TCGv_i32 dtlb = tcg_const_i32(par[0]); gen_helper_itlb(cpu_env, cpu_R[arg[0]], dtlb); /* This could change memory mapping, so exit tb */ gen_jumpi_check_loop_end(dc, -1); tcg_temp_free(dtlb); +#endif } } @@ -1985,11 +2005,13 @@ static void translate_ptlb(DisasContext *dc, const uint32_t arg[], { if (gen_check_privilege(dc) && gen_window_check2(dc, arg[0], arg[1])) { +#ifndef CONFIG_USER_ONLY TCGv_i32 dtlb = tcg_const_i32(par[0]); tcg_gen_movi_i32(cpu_pc, dc->pc); gen_helper_ptlb(cpu_R[arg[0]], cpu_env, cpu_R[arg[1]], dtlb); tcg_temp_free(dtlb); +#endif } } @@ -2173,8 +2195,10 @@ static void translate_rtlb(DisasContext *dc, const uint32_t arg[], { static void (* const helper[])(TCGv_i32 r, TCGv_env env, TCGv_i32 a1, TCGv_i32 a2) = { +#ifndef CONFIG_USER_ONLY gen_helper_rtlb0, gen_helper_rtlb1, +#endif }; if (gen_check_privilege(dc) && @@ -2283,11 +2307,14 @@ static void translate_sext(DisasContext *dc, const uint32_t arg[], static void translate_simcall(DisasContext *dc, const uint32_t arg[], const uint32_t par[]) { +#ifndef CONFIG_USER_ONLY if (semihosting_enabled()) { if (gen_check_privilege(dc)) { gen_helper_simcall(cpu_env); } - } else { + } else +#endif + { qemu_log_mask(LOG_GUEST_ERROR, "SIMCALL but semihosting is disabled\n"); gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE); } @@ -2470,7 +2497,9 @@ static void translate_waiti(DisasContext *dc, const uint32_t arg[], const uint32_t par[]) { if (gen_check_privilege(dc)) { +#ifndef CONFIG_USER_ONLY gen_waiti(dc, arg[0]); +#endif } } @@ -2479,12 +2508,14 @@ static void translate_wtlb(DisasContext *dc, const uint32_t arg[], { if (gen_check_privilege(dc) && gen_window_check2(dc, arg[0], arg[1])) { +#ifndef CONFIG_USER_ONLY TCGv_i32 dtlb = tcg_const_i32(par[0]); gen_helper_wtlb(cpu_env, cpu_R[arg[0]], cpu_R[arg[1]], dtlb); /* This could change memory mapping, so exit tb */ gen_jumpi_check_loop_end(dc, -1); tcg_temp_free(dtlb); +#endif } } |