[Qemu-devel] [PATCH] hw/mips_cpc: kick a VP when putting it into Run state
While testing mttcg I noticed that VP0 gets stuck in a loop waiting for other VPs to come up (which never actually happens). To fix this kick VPs while they are being powered up by Cluster Power Controller. Signed-off-by: Leon Alrae --- hw/misc/mips_cpc.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/hw/misc/mips_cpc.c b/hw/misc/mips_cpc.c index 6d34574..b3ff558 100644 --- a/hw/misc/mips_cpc.c +++ b/hw/misc/mips_cpc.c @@ -38,6 +38,7 @@ static void cpc_run_vp(MIPSCPCState *cpc, uint64_t vp_run) uint64_t i = 1ULL << cs->cpu_index; if (i & vp_run & ~cpc->vp_running) { cpu_reset(cs); +qemu_cpu_kick(cs); cpc->vp_running |= i; } } -- 1.7.1
Re: [Qemu-devel] [PATCH 2/2] target-mips: reimplement SC instruction and use cmpxchg
On Wed, Sep 21, 2016 at 01:16:28PM -0700, Richard Henderson wrote: > On 09/21/2016 01:07 AM, Leon Alrae wrote: > >+tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1); > >+tcg_temp_free(addr); > >+tcg_gen_movi_tl(t0, 0); > >+tcg_gen_br(done); > >+ > >+gen_set_label(l1); > >+/* generate cmpxchg */ > >+val = tcg_temp_new(); > >+gen_load_gpr(val, rt); > >+tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val, > >+ ctx->mem_idx, tcg_mo); > >+tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval); > >+tcg_temp_free(val); > >+ > >+gen_set_label(done); > >+/* store the result into the register */ > >+gen_store_gpr(t0, rt); > > tcg_temp_free(t0); > > The only thing I would change is to duplicate the gen_store_gpr into > both branches, so that we don't have to store t0 into the stack > across the blocks. Done in v3. > > Otherwise, > > Reviewed-by: Richard Henderson Thanks for reviewing. Leon
[Qemu-devel] [PATCH v3 2/2] target-mips: reimplement SC instruction and use cmpxchg
This patch completely rewrites conditional stores. Now we use cmpxchg and no longer need separate implementations for user and system emulation. Signed-off-by: Leon Alrae Reviewed-by: Richard Henderson --- linux-user/main.c | 58 -- target-mips/cpu.h | 4 -- target-mips/helper.c| 6 +-- target-mips/helper.h| 2 - target-mips/op_helper.c | 25 --- target-mips/translate.c | 107 +--- 6 files changed, 39 insertions(+), 163 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index 0d0bf9d..bc1b307 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -2230,55 +2230,6 @@ static const uint8_t mips_syscall_args[] = { # undef MIPS_SYS # endif /* O32 */ -static int do_store_exclusive(CPUMIPSState *env) -{ -target_ulong addr; -target_ulong page_addr; -target_ulong val; -int flags; -int segv = 0; -int reg; -int d; - -addr = env->lladdr; -page_addr = addr & TARGET_PAGE_MASK; -start_exclusive(); -mmap_lock(); -flags = page_get_flags(page_addr); -if ((flags & PAGE_READ) == 0) { -segv = 1; -} else { -reg = env->llreg & 0x1f; -d = (env->llreg & 0x20) != 0; -if (d) { -segv = get_user_s64(val, addr); -} else { -segv = get_user_s32(val, addr); -} -if (!segv) { -if (val != env->llval) { -env->active_tc.gpr[reg] = 0; -} else { -if (d) { -segv = put_user_u64(env->llnewval, addr); -} else { -segv = put_user_u32(env->llnewval, addr); -} -if (!segv) { -env->active_tc.gpr[reg] = 1; -} -} -} -} -env->lladdr = -1; -if (!segv) { -env->active_tc.PC += 4; -} -mmap_unlock(); -end_exclusive(); -return segv; -} - /* Break codes */ enum { BRK_OVERFLOW = 6, @@ -2426,15 +2377,6 @@ done_syscall: } } break; -case EXCP_SC: -if (do_store_exclusive(env)) { -info.si_signo = TARGET_SIGSEGV; -info.si_errno = 0; -info.si_code = TARGET_SEGV_MAPERR; -info._sifields._sigfault._addr = env->active_tc.PC; -queue_signal(env, info.si_signo, &info); -} -break; case EXCP_DSPDIS: info.si_signo = TARGET_SIGILL; info.si_errno = 0; diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 78555b9..6c268f0 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -500,8 +500,6 @@ struct CPUMIPSState { /* XXX: Maybe make LLAddr per-TC? */ target_ulong lladdr; /* LL virtual address compared against SC */ target_ulong llval; -target_ulong llnewval; -target_ulong llreg; uint64_t CP0_LLAddr_rw_bitmask; int CP0_LLAddr_shift; target_ulong CP0_WatchLo[8]; @@ -796,8 +794,6 @@ enum { EXCP_LAST = EXCP_TLBRI, }; -/* Dummy exception for conditional stores. */ -#define EXCP_SC 0x100 /* * This is an interrnally generated WAKE request line. diff --git a/target-mips/helper.c b/target-mips/helper.c index c864b15..67b19e6 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -958,10 +958,8 @@ void QEMU_NORETURN do_raise_exception_err(CPUMIPSState *env, { CPUState *cs = CPU(mips_env_get_cpu(env)); -if (exception < EXCP_SC) { -qemu_log_mask(CPU_LOG_INT, "%s: %d %d\n", - __func__, exception, error_code); -} +qemu_log_mask(CPU_LOG_INT, "%s: %d %d\n", + __func__, exception, error_code); cs->exception_index = exception; env->error_code = error_code; diff --git a/target-mips/helper.h b/target-mips/helper.h index 666936c..dd68751 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -13,10 +13,8 @@ DEF_HELPER_4(swr, void, env, tl, tl, int) #ifndef CONFIG_USER_ONLY DEF_HELPER_3(ll, tl, env, tl, int) -DEF_HELPER_4(sc, tl, env, tl, tl, int) #ifdef TARGET_MIPS64 DEF_HELPER_3(lld, tl, env, tl, int) -DEF_HELPER_4(scd, tl, env, tl, tl, int) #endif #endif diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index e0c9842..9f094ad 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -300,31 +300,6 @@ HELPER_LD_ATOMIC(ll, lw, 0x3) HELPER_LD_ATOMIC(lld, ld, 0x7) #endif #undef HELPER_LD_ATOMIC - -#define HELPER_ST_ATOMIC(name, ld_insn, st_insn, almask) \ -target_ulong helper_##name(CPUMIPSState *env, target_ulong arg1, \ - target_ulong arg2, int mem_idx)\ -{
[Qemu-devel] [PATCH v3 1/2] target-mips: compare virtual addresses in LL/SC sequence
Until now we have been comparing physical addresses in LL/SC sequence. Unfortunately that means that on each SC we have to do the address translation which is a quite complex operation. If we could get rid of it then it would allow us to throw away SC helpers and benefit from having common implementation of SC in user and system mode (currently we have 2 separate implementations selected by #ifdef CONFIG_USER_ONLY). Given our LL/SC emulation is already very simplified (as we only compare the address and value), using virtual addresses instead of physical does not seem to be a gross violation. Correct guest software should not rely on LL/SC if they accesses the same physical address via different virtual addresses or if page mapping gets changed between LL/SC due to manipulating tlb entries. MIPS Instruction Set Manual clearly says that an RMW sequence must use the same address in the LL and SC (virtual address, physical address, cacheability and coherency attributes must be identical). Otherwise the result of the SC is not predictable. This patch takes advantage of this fact and removes the virtual -> physical address translation from SC helper. lladdr served as Coprocessor 0 LLAddr register which captures physical address of the most recent LL instruction, and also lladdr was used for comparison with following SC physical address. This patch changes the meaning of lladdr - now it will only keep the virtual address of the most recent LL. Additionally we introduce CP0_LLAddr which is the actual Coperocessor 0 LLAddr register that guest can access. Signed-off-by: Leon Alrae --- target-mips/cpu.h | 3 ++- target-mips/machine.c | 7 --- target-mips/op_helper.c | 29 + target-mips/translate.c | 4 ++-- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 5182dc7..78555b9 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -494,10 +494,11 @@ struct CPUMIPSState { #define CP0C5_NFExists 0 int32_t CP0_Config6; int32_t CP0_Config7; +uint64_t CP0_LLAddr; uint64_t CP0_MAAR[MIPS_MAAR_MAX]; int32_t CP0_MAARI; /* XXX: Maybe make LLAddr per-TC? */ -uint64_t lladdr; +target_ulong lladdr; /* LL virtual address compared against SC */ target_ulong llval; target_ulong llnewval; target_ulong llreg; diff --git a/target-mips/machine.c b/target-mips/machine.c index a27f2f1..deebdf2 100644 --- a/target-mips/machine.c +++ b/target-mips/machine.c @@ -206,8 +206,8 @@ const VMStateDescription vmstate_tlb = { const VMStateDescription vmstate_mips_cpu = { .name = "cpu", -.version_id = 8, -.minimum_version_id = 8, +.version_id = 9, +.minimum_version_id = 9, .post_load = cpu_post_load, .fields = (VMStateField[]) { /* Active TC */ @@ -274,9 +274,10 @@ const VMStateDescription vmstate_mips_cpu = { VMSTATE_INT32(env.CP0_Config3, MIPSCPU), VMSTATE_INT32(env.CP0_Config6, MIPSCPU), VMSTATE_INT32(env.CP0_Config7, MIPSCPU), +VMSTATE_UINT64(env.CP0_LLAddr, MIPSCPU), VMSTATE_UINT64_ARRAY(env.CP0_MAAR, MIPSCPU, MIPS_MAAR_MAX), VMSTATE_INT32(env.CP0_MAARI, MIPSCPU), -VMSTATE_UINT64(env.lladdr, MIPSCPU), +VMSTATE_UINTTL(env.lladdr, MIPSCPU), VMSTATE_UINTTL_ARRAY(env.CP0_WatchLo, MIPSCPU, 8), VMSTATE_INT32_ARRAY(env.CP0_WatchHi, MIPSCPU, 8), VMSTATE_UINTTL(env.CP0_XContext, MIPSCPU), diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index ea2f2ab..e0c9842 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -271,15 +271,15 @@ static inline hwaddr do_translate_address(CPUMIPSState *env, target_ulong address, int rw, uintptr_t retaddr) { -hwaddr lladdr; +hwaddr paddr; CPUState *cs = CPU(mips_env_get_cpu(env)); -lladdr = cpu_mips_translate_address(env, address, rw); +paddr = cpu_mips_translate_address(env, address, rw); -if (lladdr == -1LL) { +if (paddr == -1LL) { cpu_loop_exit_restore(cs, retaddr); } else { -return lladdr; +return paddr; } } @@ -290,7 +290,8 @@ target_ulong helper_##name(CPUMIPSState *env, target_ulong arg, int mem_idx) \ env->CP0_BadVAddr = arg; \ do_raise_exception(env, EXCP_AdEL, GETPC()); \ } \ -env->lladdr = do_translate_address(env, arg, 0, GETPC()); \ +env->CP0_LLAddr = do_translate_address(env, arg, 0, GETPC()); \ +env->lladdr = arg;\ env->llval = do_##insn(env, arg, mem_idx, GETPC());
[Qemu-devel] [PATCH v3 0/2] target-mips: rework conditional stores for mttcg
These two patches change MIPS conditional stores for mttcg. Version 2 is here: https://lists.nongnu.org/archive/html/qemu-devel/2016-09/msg05005.html v3: * duplicate gen_store_gpr in both branches to avoid tcg_temp_local (Richard) v2: * improved and simplified SC implementation according to Richard's comments Leon Alrae (2): target-mips: compare virtual addresses in LL/SC sequence target-mips: reimplement SC instruction and use cmpxchg linux-user/main.c | 58 - target-mips/cpu.h | 7 +-- target-mips/helper.c| 6 +-- target-mips/helper.h| 2 - target-mips/machine.c | 7 +-- target-mips/op_helper.c | 52 +++ target-mips/translate.c | 111 +--- 7 files changed, 63 insertions(+), 180 deletions(-) -- 2.7.4
[Qemu-devel] [PULL 4/9] linux-user: Fix TARGET_F_GETOWN definition for Mips
From: Aleksandar Markovic For some reason, Qemu's TARGET_F_GETOWN constant for Mips does not match the correct value of correspondent F_GETOWN. This patch fixes this problem. For reference, see Mips' F_GETOWN definition in Linux kernel at arch/mips/include/uapi/asm/fcntl.h#L44. This patch also fixes some fcntl()-related LTP tests for Qemu user mode for Mips. Signed-off-by: Miodrag Dinic Signed-off-by: Aleksandar Markovic Reviewed-by: Laurent Vivier Reviewed-by: Leon Alrae Acked-by: Riku Voipio Signed-off-by: Leon Alrae --- linux-user/syscall_defs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index d50878b..925feda 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -2164,7 +2164,7 @@ struct target_statfs64 { #define TARGET_F_SETLK 6 #define TARGET_F_SETLKW7 #define TARGET_F_SETOWN24 /* for sockets. */ -#define TARGET_F_GETOWN25 /* for sockets. */ +#define TARGET_F_GETOWN23 /* for sockets. */ #else #define TARGET_F_GETLK 5 #define TARGET_F_SETLK 6 -- 2.7.4
[Qemu-devel] [PULL 3/9] linux-user: Fix TARGET_SIOCATMARK definition for Mips
From: Aleksandar Markovic This patch fixes wrong definition of TARGET_SIOCATMARK for mips, alpha, and sh4. The current definition is: #define SIOCATMARK 0x8905 while the correct definition is: #define SIOCATMARK TARGET_IOR('s', 7, int) See Linux kernel source file arch/mips/include/uapi/asm/sockios.h#L19 for reference. This patch also a fixes LTP test failure for test sockioctl01, for mips, alpha, and sh4. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Reviewed-by: Laurent Vivier Reviewed-by: Leon Alrae Acked-by: Riku Voipio Signed-off-by: Leon Alrae --- linux-user/syscall_defs.h | 4 1 file changed, 4 insertions(+) diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 5c19c5c..d50878b 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -898,7 +898,11 @@ struct target_pollfd { #define TARGET_KDSETLED0x4B32 /* set led state [lights, not flags] */ #define TARGET_KDSIGACCEPT 0x4B4E +#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_SH4) +#define TARGET_SIOCATMARK TARGET_IOR('s', 7, int) +#else #define TARGET_SIOCATMARK 0x8905 +#endif /* Networking ioctls */ #define TARGET_SIOCADDRT 0x890B /* add routing table entry */ -- 2.7.4
[Qemu-devel] [PULL 2/9] target-mips: generate fences
Make use of memory barrier TCG opcode in MIPS front end. Signed-off-by: Leon Alrae Reviewed-by: Richard Henderson --- target-mips/translate.c | 32 ++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index bab52cb..55c2ca0 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -13109,6 +13109,34 @@ static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd, tcg_temp_free(t1); } +static void gen_sync(int stype) +{ +TCGBar tcg_mo = TCG_BAR_SC; + +switch (stype) { +case 0x4: /* SYNC_WMB */ +tcg_mo |= TCG_MO_ST_ST; +break; +case 0x10: /* SYNC_MB */ +tcg_mo |= TCG_MO_ALL; +break; +case 0x11: /* SYNC_ACQUIRE */ +tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST; +break; +case 0x12: /* SYNC_RELEASE */ +tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST; +break; +case 0x13: /* SYNC_RMB */ +tcg_mo |= TCG_MO_LD_LD; +break; +default: +tcg_mo |= TCG_MO_ALL; +break; +} + +tcg_gen_mb(tcg_mo); +} + static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs) { int extension = (ctx->opcode >> 6) & 0x3f; @@ -13384,7 +13412,7 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs) case 0x2d: switch (minor) { case SYNC: -/* NOP */ +gen_sync(extract32(ctx->opcode, 16, 5)); break; case SYSCALL: generate_exception_end(ctx, EXCP_SYSCALL); @@ -17201,7 +17229,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) break; case OPC_SYNC: check_insn(ctx, ISA_MIPS2); -/* Treat as NOP. */ +gen_sync(extract32(ctx->opcode, 6, 5)); break; #if defined(TARGET_MIPS64) -- 2.7.4
[Qemu-devel] [PULL 7/9] linux-user: Fix certain argument alignment cases for Mips64
From: Aleksandar Markovic The function that is changed in this patch is supposed to indicate that there was certain argument rearrangement related to 64-bit arguments on 32-bit platforms. The background on such rearrangements can be found, for example, in the man page for syscall(2). However, for 64-bit Mips architectures there is no such rearrangement, and this patch reflects it. Signed-off-by: Aleksandar Rikalo Signed-off-by: Aleksandar Markovic Reviewed-by: Laurent Vivier Reviewed-by: Leon Alrae Acked-by: Riku Voipio Signed-off-by: Leon Alrae --- linux-user/syscall.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 7aa2c1d..116e463 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -658,7 +658,7 @@ static inline int next_free_host_timer(void) static inline int regpairs_aligned(void *cpu_env) { return CPUARMState *)cpu_env)->eabi) == 1) ; } -#elif defined(TARGET_MIPS) +#elif defined(TARGET_MIPS) && (TARGET_ABI_BITS == 32) static inline int regpairs_aligned(void *cpu_env) { return 1; } #elif defined(TARGET_PPC) && !defined(TARGET_PPC64) /* SysV AVI for PPC32 expects 64bit parameters to be passed on odd/even pairs -- 2.7.4
[Qemu-devel] [PULL 9/9] linux-user: Add missing Mips syscalls items in strace.list
From: Aleksandar Markovic Without this patch, a number of Mips syscalls will be logged in the following way (in this example, this is an invocation of accept4()): 86906 Unknown syscall 4334 This patch provides standard Qemu's strace output for such cases, like this: 95861 accept4(3,1996486000,1996486016,128,0,0) = 5 Such output may be further improved by providing strace-related functions that handle only particular syscalls, but this is beyond the scope of this patch. Signed-off-by: Aleksandar Markovic Reviewed-by: Laurent Vivier Acked-by: Riku Voipio Signed-off-by: Leon Alrae --- linux-user/strace.list | 114 + 1 file changed, 114 insertions(+) diff --git a/linux-user/strace.list b/linux-user/strace.list index aa967a2..608f7e0 100644 --- a/linux-user/strace.list +++ b/linux-user/strace.list @@ -6,6 +6,9 @@ #ifdef TARGET_NR_accept { TARGET_NR_accept, "accept" , NULL, print_accept, NULL }, #endif +#ifdef TARGET_NR_accept4 +{ TARGET_NR_accept4, "accept4" , NULL, NULL, NULL }, +#endif #ifdef TARGET_NR_access { TARGET_NR_access, "access" , NULL, print_access, NULL }, #endif @@ -39,6 +42,9 @@ #ifdef TARGET_NR_bind { TARGET_NR_bind, "bind" , NULL, NULL, NULL }, #endif +#ifdef TARGET_NR_bpf +{ TARGET_NR_bpf, "bpf" , NULL, NULL, NULL }, +#endif #ifdef TARGET_NR_break { TARGET_NR_break, "break" , NULL, NULL, NULL }, #endif @@ -123,18 +129,30 @@ #ifdef TARGET_NR_epoll_ctl_old { TARGET_NR_epoll_ctl_old, "epoll_ctl_old" , NULL, NULL, NULL }, #endif +#ifdef TARGET_NR_epoll_pwait +{ TARGET_NR_epoll_pwait, "epoll_pwait" , NULL, NULL, NULL }, +#endif #ifdef TARGET_NR_epoll_wait { TARGET_NR_epoll_wait, "epoll_wait" , NULL, NULL, NULL }, #endif #ifdef TARGET_NR_epoll_wait_old { TARGET_NR_epoll_wait_old, "epoll_wait_old" , NULL, NULL, NULL }, #endif +#ifdef TARGET_NR_eventfd +{ TARGET_NR_eventfd, "eventfd" , NULL, NULL, NULL }, +#endif +#ifdef TARGET_NR_eventfd2 +{ TARGET_NR_eventfd2, "eventfd2" , NULL, NULL, NULL }, +#endif #ifdef TARGET_NR_execv { TARGET_NR_execv, "execv" , NULL, print_execv, NULL }, #endif #ifdef TARGET_NR_execve { TARGET_NR_execve, "execve" , NULL, print_execve, NULL }, #endif +#ifdef TARGET_NR_execveat +{ TARGET_NR_execveat, "execveat" , NULL, NULL, NULL }, +#endif #ifdef TARGET_NR_exec_with_loader { TARGET_NR_exec_with_loader, "exec_with_loader" , NULL, NULL, NULL }, #endif @@ -156,6 +174,15 @@ #ifdef TARGET_NR_fadvise64_64 { TARGET_NR_fadvise64_64, "fadvise64_64" , NULL, NULL, NULL }, #endif +#ifdef TARGET_NR_fallocate +{ TARGET_NR_fallocate, "fallocate" , NULL, NULL, NULL }, +#endif +#ifdef TARGET_NR_fanotify_init +{ TARGET_NR_fanotify_init, "fanotify_init" , NULL, NULL, NULL }, +#endif +#ifdef TARGET_NR_fanotify_mark +{ TARGET_NR_fanotify_mark, "fanotify_mark" , NULL, NULL, NULL }, +#endif #ifdef TARGET_NR_fchdir { TARGET_NR_fchdir, "fchdir" , NULL, NULL, NULL }, #endif @@ -186,6 +213,9 @@ #ifdef TARGET_NR_fgetxattr { TARGET_NR_fgetxattr, "fgetxattr" , NULL, NULL, NULL }, #endif +#ifdef TARGET_NR_finit_module +{ TARGET_NR_finit_module, "finit_module" , NULL, NULL, NULL }, +#endif #ifdef TARGET_NR_flistxattr { TARGET_NR_flistxattr, "flistxattr" , NULL, NULL, NULL }, #endif @@ -231,6 +261,9 @@ #ifdef TARGET_NR_futimesat { TARGET_NR_futimesat, "futimesat" , NULL, print_futimesat, NULL }, #endif +#ifdef TARGET_NR_getcpu +{ TARGET_NR_getcpu, "getcpu" , "%s(%p,%d)", NULL, NULL }, +#endif #ifdef TARGET_NR_getcwd { TARGET_NR_getcwd, "getcwd" , "%s(%p,%d)", NULL, NULL }, #endif @@ -306,6 +339,9 @@ #ifdef TARGET_NR_getpriority { TARGET_NR_getpriority, "getpriority", "%s(%#x,%#x)", NULL, NULL }, #endif +#ifdef TARGET_NR_getrandom +{ TARGET_NR_getrandom, "getrandom", NULL, NULL, NULL }, +#endif #ifdef TARGET_NR_getresgid { TARGET_NR_getresgid, "getresgid" , NULL, NULL, NULL }, #endif @@ -379,6 +415,9 @@ #ifdef TARGET_NR_inotify_init { TARGET_NR_inotify_init, "inotify_init" , NULL, NULL, NULL }, #endif +#ifdef TARGET_NR_inotify_init1 +{ TARGET_NR_inotify_init1, "inotify_init1" , NULL, NULL, NULL }, +#endif #ifdef TARGET_NR_inotify_rm_watch { TARGET_NR_inotify_rm_watch, "inotify_rm_watch" , NULL, NULL, NULL }, #endif @@ -415,6 +454,9 @@ #ifdef TARGET_NR_ipc { TARGET_NR_ipc, "ipc" , NULL, print_ipc, NULL }, #endif +#ifdef TARGET_NR_kcmp +{ TARGET_NR_kcmp, "kcmp" , NULL, NULL, NULL }, +#endif #ifdef TARGET_NR_kexec_load { TARGET_NR_kexec_load, "kexec_load" , NULL, NULL, NULL }, #endif @@ -484,6 +526,12 @@ #ifdef TARGET_NR_mbind { TARGET_NR_mbind, "mbind" , NULL, NULL, NULL }, #end
[Qemu-devel] [PULL 5/9] linux-user: Fix structure target_flock definition for Mips
From: Aleksandar Markovic Structure flock is defined for Mips in a way different from any other platform. For reference, see Linux kernel source code files: arch/mips/include/uapi/asm/fcntl.h, line 63 (for Mips) include/uapi/asm-generic/fcntl.h, line 195 (for all other platforms) This patch fix this problem, by amending structure target_flock, for Mips only. Besides, this patch fixes LTP tests fcntl11, fcntl17, fcntl19, fcntl20, and fcntl21, which are currently failing, if executed in Qemu user mode for Mips platforms. Signed-off-by: Aleksandar Markovic Reviewed-by: Laurent Vivier Reviewed-by: Leon Alrae Acked-by: Riku Voipio Signed-off-by: Leon Alrae --- linux-user/syscall_defs.h | 6 ++ 1 file changed, 6 insertions(+) diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 925feda..9fdbe86 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -2333,7 +2333,13 @@ struct target_flock { short l_whence; abi_long l_start; abi_long l_len; +#if defined(TARGET_MIPS) +abi_long l_sysid; +#endif int l_pid; +#if defined(TARGET_MIPS) +abi_long pad[4]; +#endif }; struct target_flock64 { -- 2.7.4
[Qemu-devel] [PULL 8/9] linux-user: Add missing TARGET_EDQUOT error code for Mips
From: Aleksandar Markovic EDQUOT is defined for Mips platform in Linux kernel in such a way that it has different value than on most other platforms. However, correspondent TARGET_EDQUOT for Mips is missing in Qemu code. Moreover, TARGET_EDQUOT is missing from the table for conversion of error codes from host to target. This patch fixes these problems. Without this patch, syscalls add_key(), keyctl(), link(), mkdir(), mknod(), open(), rename(), request_key(), setxattr(), symlink(), and write() will not be able to return the right error code in some scenarios on Mips platform. (Some of these syscalls are not yet supported in Qemu, but once they are supported, they will need correct EDQUOT handling.) Signed-off-by: Aleksandar Markovic Reviewed-by: Laurent Vivier Acked-by: Riku Voipio Signed-off-by: Leon Alrae --- linux-user/mips/target_syscall.h | 2 ++ linux-user/mips64/target_syscall.h | 2 ++ linux-user/syscall.c | 1 + 3 files changed, 5 insertions(+) diff --git a/linux-user/mips/target_syscall.h b/linux-user/mips/target_syscall.h index 6c666dc..0b64b73 100644 --- a/linux-user/mips/target_syscall.h +++ b/linux-user/mips/target_syscall.h @@ -221,6 +221,8 @@ struct target_pt_regs { #undef TARGET_ENOTRECOVERABLE #define TARGET_ENOTRECOVERABLE 166 /* State not recoverable */ +#undef TARGET_EDQUOT +#define TARGET_EDQUOT 1133/* Quota exceeded */ #define UNAME_MACHINE "mips" #define UNAME_MINIMUM_RELEASE "2.6.32" diff --git a/linux-user/mips64/target_syscall.h b/linux-user/mips64/target_syscall.h index a9c17f7..6692917 100644 --- a/linux-user/mips64/target_syscall.h +++ b/linux-user/mips64/target_syscall.h @@ -218,6 +218,8 @@ struct target_pt_regs { #undef TARGET_ENOTRECOVERABLE #define TARGET_ENOTRECOVERABLE 166 /* State not recoverable */ +#undef TARGET_EDQUOT +#define TARGET_EDQUOT 1133/* Quota exceeded */ #define UNAME_MACHINE "mips64" #define UNAME_MINIMUM_RELEASE "2.6.32" diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 116e463..0815f30 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -757,6 +757,7 @@ static uint16_t host_to_target_errno_table[ERRNO_TABLE_SIZE] = { [ENAVAIL] = TARGET_ENAVAIL, [EISNAM] = TARGET_EISNAM, [EREMOTEIO]= TARGET_EREMOTEIO, +[EDQUOT]= TARGET_EDQUOT, [ESHUTDOWN]= TARGET_ESHUTDOWN, [ETOOMANYREFS] = TARGET_ETOOMANYREFS, [ETIMEDOUT]= TARGET_ETIMEDOUT, -- 2.7.4
[Qemu-devel] [PULL 6/9] linux-user: Fix structure target_semid64_ds definition for Mips
From: Aleksandar Markovic This patch corrects target_semid64_ds structure definition for Mips. See, for example definition of semid64_ds for Mips in Linux kernel: arch/mips/include/uapi/asm/sembuf.h#L13. This patch will also fix certain semaphore-related LTP tests for Mips, if they are executed in Qemu user mode for any Mips platform. Signed-off-by: Miodrag Dinic Signed-off-by: Aleksandar Markovic Reviewed-by: Peter Maydell Reviewed-by: Laurent Vivier Reviewed-by: Leon Alrae Acked-by: Riku Voipio Signed-off-by: Leon Alrae --- linux-user/mips/target_structs.h | 16 1 file changed, 16 insertions(+) diff --git a/linux-user/mips/target_structs.h b/linux-user/mips/target_structs.h index fbd9955..909ba89 100644 --- a/linux-user/mips/target_structs.h +++ b/linux-user/mips/target_structs.h @@ -45,4 +45,20 @@ struct target_shmid_ds { abi_ulong __unused2; }; +#define TARGET_SEMID64_DS + +/* + * The semid64_ds structure for the MIPS architecture. + * Note extra padding because this structure is passed back and forth + * between kernel and user space. + */ +struct target_semid64_ds { +struct target_ipc_perm sem_perm; +abi_ulong sem_otime; +abi_ulong sem_ctime; +abi_ulong sem_nsems; +abi_ulong __unused1; +abi_ulong __unused2; +}; + #endif -- 2.7.4
[Qemu-devel] [PULL 1/9] target-mips: add 24KEc CPU definition
From: André Draszik Define a new CPU definition supporting 24KEc cores, similar to the existing 24Kc, but with added support for DSP instructions and MIPS16e (and without FPU). Signed-off-by: André Draszik Signed-off-by: Leon Alrae --- target-mips/translate_init.c | 22 ++ 1 file changed, 22 insertions(+) diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c index 39ed5c4..6ae23e4 100644 --- a/target-mips/translate_init.c +++ b/target-mips/translate_init.c @@ -256,6 +256,28 @@ static const mips_def_t mips_defs[] = .mmu_type = MMU_TYPE_R4000, }, { +.name = "24KEc", +.CP0_PRid = 0x00019600, +.CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | + (MMU_TYPE_R4000 << CP0C0_MT), +.CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) | + (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) | + (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) | + (1 << CP0C1_CA), +.CP0_Config2 = MIPS_CONFIG2, +.CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_DSPP) | (0 << CP0C3_VInt), +.CP0_LLAddr_rw_bitmask = 0, +.CP0_LLAddr_shift = 4, +.SYNCI_Step = 32, +.CCRes = 2, +/* we have a DSP, but no FPU */ +.CP0_Status_rw_bitmask = 0x1378FF1F, +.SEGBITS = 32, +.PABITS = 32, +.insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP, +.mmu_type = MMU_TYPE_R4000, +}, +{ .name = "24Kf", .CP0_PRid = 0x00019300, .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | -- 2.7.4
[Qemu-devel] [PULL 0/9] target-mips queue
Hi, Here's my queue with the MIPS patches I've accumulated so far. Thanks, Leon Cc: Peter Maydell Cc: Aurelien Jarno The following changes since commit 430da7a81d356e368ccd88dcca60f38da9aa5b9a: Merge remote-tracking branch 'remotes/riku/tags/pull-linux-user-20160915' into staging (2016-09-22 15:39:54 +0100) are available in the git repository at: git://github.com/lalrae/qemu.git tags/mips-20160923 for you to fetch changes up to fea55615b2f924128e115ceb2265069561b03ef8: linux-user: Add missing Mips syscalls items in strace.list (2016-09-23 07:07:36 +0100) MIPS patches 2016-09-23 Changes: * 24KEc CPU definition * SYNC instructions make use of tcg memory barrier ops * various MIPS linux-user bug fixes Aleksandar Markovic (7): linux-user: Fix TARGET_SIOCATMARK definition for Mips linux-user: Fix TARGET_F_GETOWN definition for Mips linux-user: Fix structure target_flock definition for Mips linux-user: Fix structure target_semid64_ds definition for Mips linux-user: Fix certain argument alignment cases for Mips64 linux-user: Add missing TARGET_EDQUOT error code for Mips linux-user: Add missing Mips syscalls items in strace.list André Draszik (1): target-mips: add 24KEc CPU definition Leon Alrae (1): target-mips: generate fences linux-user/mips/target_structs.h | 16 ++ linux-user/mips/target_syscall.h | 2 + linux-user/mips64/target_syscall.h | 2 + linux-user/strace.list | 114 + linux-user/syscall.c | 3 +- linux-user/syscall_defs.h | 12 +++- target-mips/translate.c| 32 ++- target-mips/translate_init.c | 22 +++ 8 files changed, 199 insertions(+), 4 deletions(-)
[Qemu-devel] [PATCH] MAINTAINERS: update target-mips maintainers
Yongbok Kim takes over the target-mips maintenance from me. Signed-off-by: Leon Alrae --- Hi, September is my last month in ImgTec, and therefore soon I won't be able to look after target-mips code. I would like to nominate Yongbok Kim as the new co-maintainer. Yongbok contributed quite a number of MIPS features and will take care of target-mips. Thanks, Leon --- MAINTAINERS |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index b6fb84e..a43659d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -144,7 +144,7 @@ F: disas/microblaze.c MIPS M: Aurelien Jarno -M: Leon Alrae +M: Yongbok Kim S: Maintained F: target-mips/ F: hw/mips/ -- 1.7.1
Re: [Qemu-devel] [PATCH v7 0/7] linux-user: Fix miscellaneous Mips-specific issues
On Wed, Sep 21, 2016 at 07:12:20PM +, Riku Voipio wrote: > On Wed, Sep 21, 2016 at 02:16:54PM +0100, Leon Alrae wrote: > > On Mon, Sep 19, 2016 at 01:44:37PM +0200, Aleksandar Markovic wrote: > > > From: Aleksandar Markovic > > > > > > v6->v7: > > > > > > - Rebased to the latest code. > > > - Patch 1/1 expanded to act on alpha and sh4. > > > - Naming in patch 4/7 synced with kernel naming. > > > - Change code style of patch 5/7. > > > - Corrected spelling in all patches. > > > > > > v5->v6: > > > > > > - Corrected two instances of wrong field type in the patch on > > > target_flock. > > > - Added a patch that corrects handling of EDQUOT error code for Mips. > > > - Added a patch that adds missing Mips-related items in strace.list. > > > > > > v4->v5: > > > > > > - Commit messages improved. > > > > > > v3->v4: > > > > > > - Added a patch on agrument rearangement. > > > > > > v2->v3: > > > > > > - Minor fixes in the commit messages. > > > > > > v1->v2: > > > > > > - Improved a comment in the patch about target_semid64_ds (now 4/4). > > > - Added a patch that fixes TARGET_SIOCATMARK for Mips. > > > - Changed order of patches to be more structured. > > > > > > This series fixes several wrong definitions of preprocessor constants and > > > structures in Qemu user mode, as well as two other Mips-related problems. > > > > > > Aleksandar Markovic (7): > > > linux-user: Fix TARGET_SIOCATMARK definition for Mips > > > linux-user: Fix TARGET_F_GETOWN definition for Mips > > > linux-user: Fix structure target_flock definition for Mips > > > linux-user: Fix structure target_semid64_ds definition for Mips > > > linux-user: Fix certain argument alignment cases for Mips64 > > > linux-user: Add missing TARGET_EDQUOT error code for Mips > > > linux-user: Add missing Mips syscalls items in strace.list > > > > > > linux-user/mips/target_structs.h | 16 ++ > > > linux-user/mips/target_syscall.h | 2 + > > > linux-user/mips64/target_syscall.h | 2 + > > > linux-user/strace.list | 114 > > > + > > > linux-user/syscall.c | 3 +- > > > linux-user/syscall_defs.h | 12 +++- > > > 6 files changed, 147 insertions(+), 2 deletions(-) > > > > Applied to target-mips queue, thanks. > > That's a bit unorthodox way but you have my acked-by then.. Since these are mips-specific fixes I assumed it doesn't really matter whether it goes via your or my tree (I picked up a few patches like this in the past). Anyway, thanks for ack and next time I'll check with you. Leon
Re: [Qemu-devel] [PATCH v7 0/7] linux-user: Fix miscellaneous Mips-specific issues
On Mon, Sep 19, 2016 at 01:44:37PM +0200, Aleksandar Markovic wrote: > From: Aleksandar Markovic > > v6->v7: > > - Rebased to the latest code. > - Patch 1/1 expanded to act on alpha and sh4. > - Naming in patch 4/7 synced with kernel naming. > - Change code style of patch 5/7. > - Corrected spelling in all patches. > > v5->v6: > > - Corrected two instances of wrong field type in the patch on target_flock. > - Added a patch that corrects handling of EDQUOT error code for Mips. > - Added a patch that adds missing Mips-related items in strace.list. > > v4->v5: > > - Commit messages improved. > > v3->v4: > > - Added a patch on agrument rearangement. > > v2->v3: > > - Minor fixes in the commit messages. > > v1->v2: > > - Improved a comment in the patch about target_semid64_ds (now 4/4). > - Added a patch that fixes TARGET_SIOCATMARK for Mips. > - Changed order of patches to be more structured. > > This series fixes several wrong definitions of preprocessor constants and > structures in Qemu user mode, as well as two other Mips-related problems. > > Aleksandar Markovic (7): > linux-user: Fix TARGET_SIOCATMARK definition for Mips > linux-user: Fix TARGET_F_GETOWN definition for Mips > linux-user: Fix structure target_flock definition for Mips > linux-user: Fix structure target_semid64_ds definition for Mips > linux-user: Fix certain argument alignment cases for Mips64 > linux-user: Add missing TARGET_EDQUOT error code for Mips > linux-user: Add missing Mips syscalls items in strace.list > > linux-user/mips/target_structs.h | 16 ++ > linux-user/mips/target_syscall.h | 2 + > linux-user/mips64/target_syscall.h | 2 + > linux-user/strace.list | 114 > + > linux-user/syscall.c | 3 +- > linux-user/syscall_defs.h | 12 +++- > 6 files changed, 147 insertions(+), 2 deletions(-) Applied to target-mips queue, thanks. Leon
[Qemu-devel] QEMU dtc submodule
Hi, What's the procedure to update / who can update QEMU's dtc mirror git://git.qemu.org/dtc.git which is used as submodule? There's a patch series relying on the dtc v1.4.2 tag: https://lists.nongnu.org/archive/html/qemu-devel/2016-09/msg01815.html but the dtc mirror is outdated and that tag is not there. Thanks, Leon
[Qemu-devel] [PATCH 1/2] target-mips: compare virtual addresses in LL/SC sequence
Until now we have been comparing physical addresses in LL/SC sequence. Unfortunately that means that on each SC we have to do the address translation which is a quite complex operation. If we could get rid of it then it would allow us to throw away SC helpers and benefit from having common implementation of SC in user and system mode (currently we have 2 separate implementations selected by #ifdef CONFIG_USER_ONLY). Given our LL/SC emulation is already very simplified (as we only compare the address and value), using virtual addresses instead of physical does not seem to be a gross violation. Correct guest software should not rely on LL/SC if they accesses the same physical address via different virtual addresses or if page mapping gets changed between LL/SC due to manipulating tlb entries. MIPS Instruction Set Manual clearly says that an RMW sequence must use the same address in the LL and SC (virtual address, physical address, cacheability and coherency attributes must be identical). Otherwise the result of the SC is not predictable. This patch takes advantage of this fact and removes the virtual -> physical address translation from SC helper. lladdr served as Coprocessor 0 LLAddr register which captures physical address of the most recent LL instruction, and also lladdr was used for comparison with following SC physical address. This patch changes the meaning of lladdr - now it will only keep the virtual address of the most recent LL. Additionally we introduce CP0_LLAddr which is the actual Coperocessor 0 LLAddr register that guest can access. Signed-off-by: Leon Alrae --- target-mips/cpu.h | 3 ++- target-mips/machine.c | 7 --- target-mips/op_helper.c | 29 + target-mips/translate.c | 4 ++-- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 5182dc7..78555b9 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -494,10 +494,11 @@ struct CPUMIPSState { #define CP0C5_NFExists 0 int32_t CP0_Config6; int32_t CP0_Config7; +uint64_t CP0_LLAddr; uint64_t CP0_MAAR[MIPS_MAAR_MAX]; int32_t CP0_MAARI; /* XXX: Maybe make LLAddr per-TC? */ -uint64_t lladdr; +target_ulong lladdr; /* LL virtual address compared against SC */ target_ulong llval; target_ulong llnewval; target_ulong llreg; diff --git a/target-mips/machine.c b/target-mips/machine.c index a27f2f1..deebdf2 100644 --- a/target-mips/machine.c +++ b/target-mips/machine.c @@ -206,8 +206,8 @@ const VMStateDescription vmstate_tlb = { const VMStateDescription vmstate_mips_cpu = { .name = "cpu", -.version_id = 8, -.minimum_version_id = 8, +.version_id = 9, +.minimum_version_id = 9, .post_load = cpu_post_load, .fields = (VMStateField[]) { /* Active TC */ @@ -274,9 +274,10 @@ const VMStateDescription vmstate_mips_cpu = { VMSTATE_INT32(env.CP0_Config3, MIPSCPU), VMSTATE_INT32(env.CP0_Config6, MIPSCPU), VMSTATE_INT32(env.CP0_Config7, MIPSCPU), +VMSTATE_UINT64(env.CP0_LLAddr, MIPSCPU), VMSTATE_UINT64_ARRAY(env.CP0_MAAR, MIPSCPU, MIPS_MAAR_MAX), VMSTATE_INT32(env.CP0_MAARI, MIPSCPU), -VMSTATE_UINT64(env.lladdr, MIPSCPU), +VMSTATE_UINTTL(env.lladdr, MIPSCPU), VMSTATE_UINTTL_ARRAY(env.CP0_WatchLo, MIPSCPU, 8), VMSTATE_INT32_ARRAY(env.CP0_WatchHi, MIPSCPU, 8), VMSTATE_UINTTL(env.CP0_XContext, MIPSCPU), diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index ea2f2ab..e0c9842 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -271,15 +271,15 @@ static inline hwaddr do_translate_address(CPUMIPSState *env, target_ulong address, int rw, uintptr_t retaddr) { -hwaddr lladdr; +hwaddr paddr; CPUState *cs = CPU(mips_env_get_cpu(env)); -lladdr = cpu_mips_translate_address(env, address, rw); +paddr = cpu_mips_translate_address(env, address, rw); -if (lladdr == -1LL) { +if (paddr == -1LL) { cpu_loop_exit_restore(cs, retaddr); } else { -return lladdr; +return paddr; } } @@ -290,7 +290,8 @@ target_ulong helper_##name(CPUMIPSState *env, target_ulong arg, int mem_idx) \ env->CP0_BadVAddr = arg; \ do_raise_exception(env, EXCP_AdEL, GETPC()); \ } \ -env->lladdr = do_translate_address(env, arg, 0, GETPC()); \ +env->CP0_LLAddr = do_translate_address(env, arg, 0, GETPC()); \ +env->lladdr = arg;\ env->llval = do_##insn(env, arg, mem_idx, GETPC());
[Qemu-devel] [PATCH 2/2] target-mips: reimplement SC instruction and use cmpxchg
This patch completely rewrites conditional stores. Now we use cmpxchg and no longer need separate implementations for user and system emulation. Signed-off-by: Leon Alrae --- linux-user/main.c | 58 -- target-mips/cpu.h | 4 -- target-mips/helper.c| 6 +-- target-mips/helper.h| 2 - target-mips/op_helper.c | 25 --- target-mips/translate.c | 107 +--- 6 files changed, 39 insertions(+), 163 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index 0d0bf9d..bc1b307 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -2230,55 +2230,6 @@ static const uint8_t mips_syscall_args[] = { # undef MIPS_SYS # endif /* O32 */ -static int do_store_exclusive(CPUMIPSState *env) -{ -target_ulong addr; -target_ulong page_addr; -target_ulong val; -int flags; -int segv = 0; -int reg; -int d; - -addr = env->lladdr; -page_addr = addr & TARGET_PAGE_MASK; -start_exclusive(); -mmap_lock(); -flags = page_get_flags(page_addr); -if ((flags & PAGE_READ) == 0) { -segv = 1; -} else { -reg = env->llreg & 0x1f; -d = (env->llreg & 0x20) != 0; -if (d) { -segv = get_user_s64(val, addr); -} else { -segv = get_user_s32(val, addr); -} -if (!segv) { -if (val != env->llval) { -env->active_tc.gpr[reg] = 0; -} else { -if (d) { -segv = put_user_u64(env->llnewval, addr); -} else { -segv = put_user_u32(env->llnewval, addr); -} -if (!segv) { -env->active_tc.gpr[reg] = 1; -} -} -} -} -env->lladdr = -1; -if (!segv) { -env->active_tc.PC += 4; -} -mmap_unlock(); -end_exclusive(); -return segv; -} - /* Break codes */ enum { BRK_OVERFLOW = 6, @@ -2426,15 +2377,6 @@ done_syscall: } } break; -case EXCP_SC: -if (do_store_exclusive(env)) { -info.si_signo = TARGET_SIGSEGV; -info.si_errno = 0; -info.si_code = TARGET_SEGV_MAPERR; -info._sifields._sigfault._addr = env->active_tc.PC; -queue_signal(env, info.si_signo, &info); -} -break; case EXCP_DSPDIS: info.si_signo = TARGET_SIGILL; info.si_errno = 0; diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 78555b9..6c268f0 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -500,8 +500,6 @@ struct CPUMIPSState { /* XXX: Maybe make LLAddr per-TC? */ target_ulong lladdr; /* LL virtual address compared against SC */ target_ulong llval; -target_ulong llnewval; -target_ulong llreg; uint64_t CP0_LLAddr_rw_bitmask; int CP0_LLAddr_shift; target_ulong CP0_WatchLo[8]; @@ -796,8 +794,6 @@ enum { EXCP_LAST = EXCP_TLBRI, }; -/* Dummy exception for conditional stores. */ -#define EXCP_SC 0x100 /* * This is an interrnally generated WAKE request line. diff --git a/target-mips/helper.c b/target-mips/helper.c index c864b15..67b19e6 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -958,10 +958,8 @@ void QEMU_NORETURN do_raise_exception_err(CPUMIPSState *env, { CPUState *cs = CPU(mips_env_get_cpu(env)); -if (exception < EXCP_SC) { -qemu_log_mask(CPU_LOG_INT, "%s: %d %d\n", - __func__, exception, error_code); -} +qemu_log_mask(CPU_LOG_INT, "%s: %d %d\n", + __func__, exception, error_code); cs->exception_index = exception; env->error_code = error_code; diff --git a/target-mips/helper.h b/target-mips/helper.h index 666936c..dd68751 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -13,10 +13,8 @@ DEF_HELPER_4(swr, void, env, tl, tl, int) #ifndef CONFIG_USER_ONLY DEF_HELPER_3(ll, tl, env, tl, int) -DEF_HELPER_4(sc, tl, env, tl, tl, int) #ifdef TARGET_MIPS64 DEF_HELPER_3(lld, tl, env, tl, int) -DEF_HELPER_4(scd, tl, env, tl, tl, int) #endif #endif diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index e0c9842..9f094ad 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -300,31 +300,6 @@ HELPER_LD_ATOMIC(ll, lw, 0x3) HELPER_LD_ATOMIC(lld, ld, 0x7) #endif #undef HELPER_LD_ATOMIC - -#define HELPER_ST_ATOMIC(name, ld_insn, st_insn, almask) \ -target_ulong helper_##name(CPUMIPSState *env, target_ulong arg1, \ - target_ulong arg2, int mem_idx)\ -{
[Qemu-devel] [PATCH 0/2] target-mips: rework conditional stores for mttcg
This small series changes MIPS conditional stores implementation for mttcg. Specifically we compare virtual address of LL and SC (rather than physical) which allows us to have just a single inlined implementation for user and system emulation and to use new atomic helpers. This is done in 2 steps: Patch 1: modifies existing SC implementation to use virtual addresses Patch 2: SC emulation rework and making use of cmpxchg These patches apply on top of Richard's atomic series. I've done only partial testing since many of my Linux images hit the abort() due to EXCP_ATOMIC -- but IIUC this is a missing piece in atomic helpers rather than a problem in the code gen. v2: * improved and simplified SC implementation according to Richard's comments Leon Alrae (2): target-mips: compare virtual addresses in LL/SC sequence target-mips: reimplement SC instruction and use cmpxchg linux-user/main.c | 58 - target-mips/cpu.h | 7 +-- target-mips/helper.c| 6 +-- target-mips/helper.h| 2 - target-mips/machine.c | 7 +-- target-mips/op_helper.c | 52 +++ target-mips/translate.c | 111 +--- 7 files changed, 63 insertions(+), 180 deletions(-) -- 2.7.4
Re: [Qemu-devel] [PATCH 2/2] target-mips: reimplement SC instruction and use cmpxchg
On Fri, Sep 16, 2016 at 09:48:51AM -0700, Richard Henderson wrote: > On 09/15/2016 01:44 AM, Leon Alrae wrote: > > /* Store conditional */ > >+static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset, > >+int size) > > { > >+TCGv addr, t0, val; > >+TCGLabel *l1 = gen_new_label(); > >+TCGLabel *l2 = gen_new_label(); > >+TCGLabel *done = gen_new_label(); > > > >-#ifdef CONFIG_USER_ONLY > > t0 = tcg_temp_local_new(); > >+addr = tcg_temp_local_new(); > >+/* check the alignment of the address */ > >+gen_base_offset_addr(ctx, addr, base, offset); > >+tcg_gen_andi_tl(t0, addr, size - 1); > > You shouldn't have to test the alignment here, as the alignment > should have been tested during the load-locked, and the (aligned) > address will be compared. This is to satisfy the requirement that unaligned SC generates Address Error exception. But I agree that in practice this doesn't seem particularly useful since LL will do that. > > > >+/* compare the address against that of the preceeding LL */ > >+tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l2); > >+tcg_gen_movi_tl(t0, 0); > >+tcg_gen_br(done); > ... > >+#ifdef TARGET_MIPS64 > >+case 8: /* SCD */ > >+tcg_gen_atomic_cmpxchg_i64(t0, addr, cpu_llval, val, > >+ ctx->mem_idx, MO_TEQ); > > break; > > #endif > >-case OPC_SC: > >-case R6_OPC_SC: > >-op_st_sc(t1, t0, rt, ctx); > >+case 4: /* SC */ > >+{ > >+TCGv_i32 val32 = tcg_temp_new_i32(); > >+TCGv_i32 llval32 = tcg_temp_new_i32(); > >+TCGv_i32 old32 = tcg_temp_new_i32(); > >+tcg_gen_trunc_tl_i32(val32, val); > >+tcg_gen_trunc_tl_i32(llval32, cpu_llval); > >+ > >+tcg_gen_atomic_cmpxchg_i32(old32, addr, llval32, val32, > >+ ctx->mem_idx, MO_TESL); > >+tcg_gen_ext_i32_tl(t0, old32); > > You can use tcg_gen_atomic_cmpxchg_tl so that you do not need to do > all of this truncation yourself. Which means that if you replace > the size parameter with a TCGMemOp parameter (MO_TEQ vs MO_TESL) you > can make all this code common. Ah, yes. > > Further, local temporaries are less than ideal and should be avoided > if possible. Using them results in an extra store into the local > stack frame. > > We can avoid this for addr by noting that once you have compared > addr to cpu_lladdr, you can free addr and use cpu_lladdr in the > actual cmpxchg. Ok. I'll correct in v2. Thanks, Leon
Re: [Qemu-devel] [PATCH v5 3/5] linux-user: Fix structure target_flock definition for Mips
On Mon, Sep 12, 2016 at 09:40:02PM +0200, Aleksandar Markovic wrote: > From: Aleksandar Markovic > > Structure flock is defined for Mips in a way different from any > other platform. For reference, see Linux kernel source code files: > > arch/mips/include/uapi/asm/fcntl.h#L63 (for Mips) > include/uapi/asm-generic/fcntl.h#L195 (for all other platforms) > > This patch fix this problem, by amending structure target_flock, > for Mips only. > > Besides, this patch fixes LTP tests fcntl11, fcntl17, fcntl19, fcntl20, > and fcntl21, which are currently failing, if executed in Qemu user mode > for Mips platforms. > > Signed-off-by: Aleksandar Markovic > --- > linux-user/syscall_defs.h | 6 ++ > 1 file changed, 6 insertions(+) > > diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h > index 44b1197..c40b725 100644 > --- a/linux-user/syscall_defs.h > +++ b/linux-user/syscall_defs.h > @@ -2327,7 +2327,13 @@ struct target_flock { > short l_whence; > abi_long l_start; > abi_long l_len; > +#if defined(TARGET_MIPS) > +target_long l_sysid; In n32 ABI this will have incorrect size. This should be abi_long. > +#endif > int l_pid; > +#if defined(TARGET_MIPS) > +target_long pad[4]; Same. Otherwise the series looks good to me. Thanks, Leon > +#endif > }; > > struct target_flock64 { > -- > 2.9.3 >
[Qemu-devel] [PATCH 1/2] target-mips: compare virtual addresses in LL/SC sequence
Until now we have been comparing physical addresses in LL/SC sequence. Unfortunately that means that on each SC we have to do the address translation which is a quite complex operation. If we could get rid of it then it would allow us to throw away SC helpers and benefit from having common implementation of SC in user and system mode (currently we have 2 separate implementations selected by #ifdef CONFIG_USER_ONLY). Given our LL/SC emulation is already very simplified (as we only compare the address and value), using virtual addresses instead of physical does not seem to be a gross violation. Correct guest software should not rely on LL/SC if they accesses the same physical address via different virtual addresses or if page mapping gets changed between LL/SC due to manipulating tlb entries. MIPS Instruction Set Manual clearly says that an RMW sequence must use the same address in the LL and SC (virtual address, physical address, cacheability and coherency attributes must be identical). Otherwise the result of the SC is not predictable. This patch takes advantage of this fact and removes the virtual -> physical address translation from SC helper. lladdr served as Coprocessor 0 LLAddr register which captures physical address of the most recent LL instruction, and also lladdr was used for comparison with following SC physical address. This patch changes the meaning of lladdr - now it will only keep the virtual address of the most recent LL. Additionally we introduce CP0_LLAddr which is the actual Coperocessor 0 LLAddr register that guest can access. Signed-off-by: Leon Alrae --- target-mips/cpu.h | 3 ++- target-mips/machine.c | 7 --- target-mips/op_helper.c | 29 + target-mips/translate.c | 4 ++-- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 5182dc7..78555b9 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -494,10 +494,11 @@ struct CPUMIPSState { #define CP0C5_NFExists 0 int32_t CP0_Config6; int32_t CP0_Config7; +uint64_t CP0_LLAddr; uint64_t CP0_MAAR[MIPS_MAAR_MAX]; int32_t CP0_MAARI; /* XXX: Maybe make LLAddr per-TC? */ -uint64_t lladdr; +target_ulong lladdr; /* LL virtual address compared against SC */ target_ulong llval; target_ulong llnewval; target_ulong llreg; diff --git a/target-mips/machine.c b/target-mips/machine.c index a27f2f1..deebdf2 100644 --- a/target-mips/machine.c +++ b/target-mips/machine.c @@ -206,8 +206,8 @@ const VMStateDescription vmstate_tlb = { const VMStateDescription vmstate_mips_cpu = { .name = "cpu", -.version_id = 8, -.minimum_version_id = 8, +.version_id = 9, +.minimum_version_id = 9, .post_load = cpu_post_load, .fields = (VMStateField[]) { /* Active TC */ @@ -274,9 +274,10 @@ const VMStateDescription vmstate_mips_cpu = { VMSTATE_INT32(env.CP0_Config3, MIPSCPU), VMSTATE_INT32(env.CP0_Config6, MIPSCPU), VMSTATE_INT32(env.CP0_Config7, MIPSCPU), +VMSTATE_UINT64(env.CP0_LLAddr, MIPSCPU), VMSTATE_UINT64_ARRAY(env.CP0_MAAR, MIPSCPU, MIPS_MAAR_MAX), VMSTATE_INT32(env.CP0_MAARI, MIPSCPU), -VMSTATE_UINT64(env.lladdr, MIPSCPU), +VMSTATE_UINTTL(env.lladdr, MIPSCPU), VMSTATE_UINTTL_ARRAY(env.CP0_WatchLo, MIPSCPU, 8), VMSTATE_INT32_ARRAY(env.CP0_WatchHi, MIPSCPU, 8), VMSTATE_UINTTL(env.CP0_XContext, MIPSCPU), diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index ea2f2ab..e0c9842 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -271,15 +271,15 @@ static inline hwaddr do_translate_address(CPUMIPSState *env, target_ulong address, int rw, uintptr_t retaddr) { -hwaddr lladdr; +hwaddr paddr; CPUState *cs = CPU(mips_env_get_cpu(env)); -lladdr = cpu_mips_translate_address(env, address, rw); +paddr = cpu_mips_translate_address(env, address, rw); -if (lladdr == -1LL) { +if (paddr == -1LL) { cpu_loop_exit_restore(cs, retaddr); } else { -return lladdr; +return paddr; } } @@ -290,7 +290,8 @@ target_ulong helper_##name(CPUMIPSState *env, target_ulong arg, int mem_idx) \ env->CP0_BadVAddr = arg; \ do_raise_exception(env, EXCP_AdEL, GETPC()); \ } \ -env->lladdr = do_translate_address(env, arg, 0, GETPC()); \ +env->CP0_LLAddr = do_translate_address(env, arg, 0, GETPC()); \ +env->lladdr = arg;\ env->llval = do_##insn(env, arg, mem_idx, GETPC());
[Qemu-devel] [PATCH 2/2] target-mips: reimplement SC instruction and use cmpxchg
This patch completely rewrites conditional stores. Now we use cmpxchg and no longer need separate implementations for user and system emulation. Signed-off-by: Leon Alrae --- linux-user/main.c | 58 - target-mips/cpu.h | 4 -- target-mips/helper.c| 6 +-- target-mips/helper.h| 2 - target-mips/op_helper.c | 25 - target-mips/translate.c | 131 6 files changed, 67 insertions(+), 159 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index 0d0bf9d..bc1b307 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -2230,55 +2230,6 @@ static const uint8_t mips_syscall_args[] = { # undef MIPS_SYS # endif /* O32 */ -static int do_store_exclusive(CPUMIPSState *env) -{ -target_ulong addr; -target_ulong page_addr; -target_ulong val; -int flags; -int segv = 0; -int reg; -int d; - -addr = env->lladdr; -page_addr = addr & TARGET_PAGE_MASK; -start_exclusive(); -mmap_lock(); -flags = page_get_flags(page_addr); -if ((flags & PAGE_READ) == 0) { -segv = 1; -} else { -reg = env->llreg & 0x1f; -d = (env->llreg & 0x20) != 0; -if (d) { -segv = get_user_s64(val, addr); -} else { -segv = get_user_s32(val, addr); -} -if (!segv) { -if (val != env->llval) { -env->active_tc.gpr[reg] = 0; -} else { -if (d) { -segv = put_user_u64(env->llnewval, addr); -} else { -segv = put_user_u32(env->llnewval, addr); -} -if (!segv) { -env->active_tc.gpr[reg] = 1; -} -} -} -} -env->lladdr = -1; -if (!segv) { -env->active_tc.PC += 4; -} -mmap_unlock(); -end_exclusive(); -return segv; -} - /* Break codes */ enum { BRK_OVERFLOW = 6, @@ -2426,15 +2377,6 @@ done_syscall: } } break; -case EXCP_SC: -if (do_store_exclusive(env)) { -info.si_signo = TARGET_SIGSEGV; -info.si_errno = 0; -info.si_code = TARGET_SEGV_MAPERR; -info._sifields._sigfault._addr = env->active_tc.PC; -queue_signal(env, info.si_signo, &info); -} -break; case EXCP_DSPDIS: info.si_signo = TARGET_SIGILL; info.si_errno = 0; diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 78555b9..6c268f0 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -500,8 +500,6 @@ struct CPUMIPSState { /* XXX: Maybe make LLAddr per-TC? */ target_ulong lladdr; /* LL virtual address compared against SC */ target_ulong llval; -target_ulong llnewval; -target_ulong llreg; uint64_t CP0_LLAddr_rw_bitmask; int CP0_LLAddr_shift; target_ulong CP0_WatchLo[8]; @@ -796,8 +794,6 @@ enum { EXCP_LAST = EXCP_TLBRI, }; -/* Dummy exception for conditional stores. */ -#define EXCP_SC 0x100 /* * This is an interrnally generated WAKE request line. diff --git a/target-mips/helper.c b/target-mips/helper.c index c864b15..67b19e6 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -958,10 +958,8 @@ void QEMU_NORETURN do_raise_exception_err(CPUMIPSState *env, { CPUState *cs = CPU(mips_env_get_cpu(env)); -if (exception < EXCP_SC) { -qemu_log_mask(CPU_LOG_INT, "%s: %d %d\n", - __func__, exception, error_code); -} +qemu_log_mask(CPU_LOG_INT, "%s: %d %d\n", + __func__, exception, error_code); cs->exception_index = exception; env->error_code = error_code; diff --git a/target-mips/helper.h b/target-mips/helper.h index 666936c..dd68751 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -13,10 +13,8 @@ DEF_HELPER_4(swr, void, env, tl, tl, int) #ifndef CONFIG_USER_ONLY DEF_HELPER_3(ll, tl, env, tl, int) -DEF_HELPER_4(sc, tl, env, tl, tl, int) #ifdef TARGET_MIPS64 DEF_HELPER_3(lld, tl, env, tl, int) -DEF_HELPER_4(scd, tl, env, tl, tl, int) #endif #endif diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index e0c9842..9f094ad 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -300,31 +300,6 @@ HELPER_LD_ATOMIC(ll, lw, 0x3) HELPER_LD_ATOMIC(lld, ld, 0x7) #endif #undef HELPER_LD_ATOMIC - -#define HELPER_ST_ATOMIC(name, ld_insn, st_insn, almask) \ -target_ulong helper_##name(CPUMIPSState *env, target_ulong arg1, \ - target_ulong arg2, int mem_idx)\ -{
[Qemu-devel] [PATCH 0/2] target-mips: rework conditional stores for mttcg
This small series changes MIPS conditional stores implementation for mttcg. Specifically we compare virtual address of LL and SC (rather than physical) which allows us to have just a single inlined implementation for user and system emulation and to use new atomic helpers. This is done in 2 steps: Patch 1: modifies existing SC implementation to use virtual addresses Patch 2: SC emulation rework and making use of cmpxchg These patches apply on top of Richard's atomic series. I've done only partial testing since many of my Linux images hit the abort() due to EXCP_ATOMIC -- but IIUC this is a missing piece in atomic helpers rather than a problem in the code gen. Leon Alrae (2): target-mips: compare virtual addresses in LL/SC sequence target-mips: reimplement SC instruction and use cmpxchg linux-user/main.c | 58 - target-mips/cpu.h | 7 +-- target-mips/helper.c| 6 +-- target-mips/helper.h| 2 - target-mips/machine.c | 7 +-- target-mips/op_helper.c | 52 ++- target-mips/translate.c | 135 7 files changed, 91 insertions(+), 176 deletions(-) -- 2.7.4
Re: [Qemu-devel] [PATCH v3 13/34] tcg: Add atomic helpers
On Mon, Sep 12, 2016 at 09:13:10AM -0700, Richard Henderson wrote: > On 09/12/2016 12:59 AM, Leon Alrae wrote: > >On Fri, Sep 09, 2016 at 09:26:29AM -0700, Richard Henderson wrote: > >>On 09/09/2016 07:46 AM, Leon Alrae wrote: > >>>Wouldn't it be useful if tcg.h provided also aliases for _le/_be atomic > >>>helpers (equivalent to helper_ret_X_mmu) so that in target-* code we > >>>wouldn't > >>>need to care about the endianness (specifically I'm thinking about SC in > >>>MIPS > >>>where I need to select between helper_atomic_cmpxchgl_le_mmu() and > >>>helper_atomic_cmpxchgl_be_mmu()). > >> > >>Perhaps. I would have hoped that you could do the SC inline now > >>though, and tcg_gen_atomic_cmpxchg() will do the selection for you. > > > >On every SC we need to do the virtual -> physical address translation as we > >have to compare the physical address against that of the preceeding LL. > >This operation seems too complex to be inlined :( > > What happens if you do virtual address comparisons, like everyone > else? It might not be strictly correct, but in practice I bet its > no worse than using cmpxchg in the first place. Yeah, probably true. Moreover, MIPS Instruction Set Manual explicitly says that an RMW sequence must use the same address in the LL and SC (virtual address, physical address, cacheability and coherency attributes must be identical). Otherwise the result of the SC is not predictable. I'll try to come up with simpler SC implementation using virtual addresses and tcg_gen_atomic_cmpxchg(). Thanks, Leon
Re: [Qemu-devel] [PATCH v3 13/34] tcg: Add atomic helpers
On Fri, Sep 09, 2016 at 09:26:29AM -0700, Richard Henderson wrote: > On 09/09/2016 07:46 AM, Leon Alrae wrote: > >Wouldn't it be useful if tcg.h provided also aliases for _le/_be atomic > >helpers (equivalent to helper_ret_X_mmu) so that in target-* code we wouldn't > >need to care about the endianness (specifically I'm thinking about SC in MIPS > >where I need to select between helper_atomic_cmpxchgl_le_mmu() and > >helper_atomic_cmpxchgl_be_mmu()). > > Perhaps. I would have hoped that you could do the SC inline now > though, and tcg_gen_atomic_cmpxchg() will do the selection for you. On every SC we need to do the virtual -> physical address translation as we have to compare the physical address against that of the preceeding LL. This operation seems too complex to be inlined :( Leon
Re: [Qemu-devel] [PATCH v3 13/34] tcg: Add atomic helpers
On Sat, Sep 03, 2016 at 09:39:41PM +0100, Richard Henderson wrote: > --- a/tcg/tcg.h > +++ b/tcg/tcg.h > @@ -1175,6 +1175,59 @@ uint64_t helper_be_ldq_cmmu(CPUArchState *env, > target_ulong addr, > # define helper_ret_ldq_cmmu helper_le_ldq_cmmu > #endif > > +uint32_t helper_atomic_cmpxchgb_mmu(CPUArchState *env, target_ulong addr, > +uint32_t cmpv, uint32_t newv, > +TCGMemOpIdx oi, uintptr_t retaddr); > +uint32_t helper_atomic_cmpxchgw_le_mmu(CPUArchState *env, target_ulong addr, > + uint32_t cmpv, uint32_t newv, > + TCGMemOpIdx oi, uintptr_t retaddr); > +uint32_t helper_atomic_cmpxchgl_le_mmu(CPUArchState *env, target_ulong addr, > + uint32_t cmpv, uint32_t newv, > + TCGMemOpIdx oi, uintptr_t retaddr); > +uint64_t helper_atomic_cmpxchgq_le_mmu(CPUArchState *env, target_ulong addr, > + uint64_t cmpv, uint64_t newv, > + TCGMemOpIdx oi, uintptr_t retaddr); > +uint32_t helper_atomic_cmpxchgw_be_mmu(CPUArchState *env, target_ulong addr, > + uint32_t cmpv, uint32_t newv, > + TCGMemOpIdx oi, uintptr_t retaddr); > +uint32_t helper_atomic_cmpxchgl_be_mmu(CPUArchState *env, target_ulong addr, > + uint32_t cmpv, uint32_t newv, > + TCGMemOpIdx oi, uintptr_t retaddr); > +uint64_t helper_atomic_cmpxchgq_be_mmu(CPUArchState *env, target_ulong addr, > + uint64_t cmpv, uint64_t newv, > + TCGMemOpIdx oi, uintptr_t retaddr); Wouldn't it be useful if tcg.h provided also aliases for _le/_be atomic helpers (equivalent to helper_ret_X_mmu) so that in target-* code we wouldn't need to care about the endianness (specifically I'm thinking about SC in MIPS where I need to select between helper_atomic_cmpxchgl_le_mmu() and helper_atomic_cmpxchgl_be_mmu()). Thanks, Leon
Re: [Qemu-devel] [PATCH v3 13/34] tcg: Add atomic helpers
> +#define GEN_ATOMIC_HELPER(NAME, OP, NEW)\ > +static void * const table_##NAME[16] = {\ > +[MO_8] = gen_helper_atomic_##NAME##b, \ > +[MO_16 | MO_LE] = gen_helper_atomic_##NAME##w_le, \ > +[MO_16 | MO_BE] = gen_helper_atomic_##NAME##w_be, \ > +[MO_32 | MO_LE] = gen_helper_atomic_##NAME##l_le, \ > +[MO_32 | MO_BE] = gen_helper_atomic_##NAME##l_be, \ > +[MO_64 | MO_LE] = gen_helper_atomic_##NAME##q_le, \ > +[MO_64 | MO_BE] = gen_helper_atomic_##NAME##q_be, \ > +}; \ > +void tcg_gen_atomic_##NAME##_i32\ > +(TCGv_i32 ret, TCGv addr, TCGv_i32 val, TCGArg idx, TCGMemOp memop) \ > +{ \ > +if (parallel_cpus) {\ > +do_atomic_op_i32(ret, addr, val, idx, memop, table_##NAME); \ > +} else {\ > +do_nonatomic_op_i32(ret, addr, val, idx, memop, NEW,\ > +tcg_gen_##OP##_i32);\ > +} \ > +} \ > +void tcg_gen_atomic_##NAME##_i64\ > +(TCGv_i64 ret, TCGv addr, TCGv_i64 val, TCGArg idx, TCGMemOp memop) \ > +{ \ > +if (parallel_cpus) {\ > +do_atomic_op_i64(ret, addr, val, idx, memop, table_##NAME); \ > +} else {\ > +do_nonatomic_op_i64(ret, addr, val, idx, memop, NEW,\ > +tcg_gen_##OP##_i64);\ > +} \ > +} > + > +GEN_ATOMIC_HELPER(fetch_add, add, 0) > +GEN_ATOMIC_HELPER(fetch_and, and, 0) > +GEN_ATOMIC_HELPER(fetch_or, or, 0) > +GEN_ATOMIC_HELPER(fetch_xor, xor, 0) > + > +GEN_ATOMIC_HELPER(add_fetch, add, 1) > +GEN_ATOMIC_HELPER(and_fetch, and, 1) > +GEN_ATOMIC_HELPER(or_fetch, or, 1) > +GEN_ATOMIC_HELPER(xor_fetch, xor, 1) This causes build errors on CentOS6.5 (where __ATOMIC_RELAXED is undefined): /user/lea/dev/qemu/tcg/tcg-op.c:2280: error: ‘gen_helper_atomic_fetch_addb’ undeclared here (not in a function) /user/lea/dev/qemu/tcg/tcg-op.c:2280: error: ‘gen_helper_atomic_fetch_addw_le’ undeclared here (not in a function) /user/lea/dev/qemu/tcg/tcg-op.c:2280: error: ‘gen_helper_atomic_fetch_addw_be’ undeclared here (not in a function) (...) The fix I've been using locally while working on enabling MTTCG for MIPS: diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h index 5542416..818a5a4 100644 --- a/include/qemu/atomic.h +++ b/include/qemu/atomic.h @@ -409,22 +409,22 @@ /* Provide shorter names for GCC atomic builtins. */ #define atomic_fetch_inc(ptr) __sync_fetch_and_add(ptr, 1) #define atomic_fetch_dec(ptr) __sync_fetch_and_add(ptr, -1) -#define atomic_fetch_add __sync_fetch_and_add -#define atomic_fetch_sub __sync_fetch_and_sub -#define atomic_fetch_and __sync_fetch_and_and -#define atomic_fetch_or__sync_fetch_and_or -#define atomic_fetch_xor __sync_fetch_and_xor +#define atomic_fetch_add(ptr, n) __sync_fetch_and_add(ptr, n) +#define atomic_fetch_sub(ptr, n) __sync_fetch_and_sub(ptr, n) +#define atomic_fetch_and(ptr, n) __sync_fetch_and_and(ptr, n) +#define atomic_fetch_or(ptr, n) __sync_fetch_and_or(ptr, n) +#define atomic_fetch_xor(ptr, n) __sync_fetch_and_xor(ptr, n) #define atomic_inc_fetch(ptr) __sync_add_and_fetch(ptr, 1) #define atomic_dec_fetch(ptr) __sync_add_and_fetch(ptr, -1) -#define atomic_add_fetch __sync_add_and_fetch -#define atomic_sub_fetch __sync_sub_and_fetch -#define atomic_and_fetch __sync_and_and_fetch -#define atomic_or_fetch__sync_or_and_fetch -#define atomic_xor_fetch __sync_xor_and_fetch - -#define atomic_cmpxchg __sync_val_compare_and_swap -#define atomic_cmpxchg__nocheck atomic_cmpxchg +#define atomic_add_fetch(ptr, n) __sync_add_and_fetch(ptr, n) +#define atomic_sub_fetch(ptr, n) __sync_sub_and_fetch(ptr, n) +#define atomic_and_fetch(ptr, n) __sync_and_and_fetch(ptr, n) +#define atomic_or_fetch(ptr, n) __sync_or_and_fetch(ptr, n) +#define atomic_xor_fetch(ptr, n) __sync_xor_and_fetch(ptr, n) + +#define atomic_cmpxchg(ptr, old, new) __sync_val_compare_and_swap(ptr, old, new) +#define atomic_cmpxchg__nocheck(ptr, old, new) atomic_cmpxchg(ptr, old, new) /* And even shorter n
Re: [Qemu-devel] [PATCH v3 05/34] int128: Add int128_make128
On Sat, Sep 03, 2016 at 09:39:33PM +0100, Richard Henderson wrote: > Allows Int128 to be used more generally, rather than having to > begin with 64-bit inputs and accumulate. > > Signed-off-by: Richard Henderson > --- > include/qemu/int128.h | 20 +++- > 1 file changed, 15 insertions(+), 5 deletions(-) > > diff --git a/include/qemu/int128.h b/include/qemu/int128.h > index 08f1db1..67440fa 100644 > --- a/include/qemu/int128.h > +++ b/include/qemu/int128.h > @@ -10,6 +10,11 @@ static inline Int128 int128_make64(uint64_t a) > return a; > } > > +static inline Int128 int128_make128(uint64_t lo, uint64_t hi) > +{ > +return (unsigned __int128)hi << 64 | lo; > +} > + This causes build failures for me on CentOS6.5: /user/lea/dev/qemu/include/qemu/int128.h:7: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘Int128’ /user/lea/dev/qemu/include/qemu/int128.h:9: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘int128_make64’ /user/lea/dev/qemu/include/qemu/int128.h:14: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘int128_make128’ (...) This is because CONFIG_INT128 is set if test for __int128_t succeeds, not __int128. The following change on top of patches 4 and 5 in this series fixes the problem for me: diff --git a/include/qemu/int128.h b/include/qemu/int128.h index 261b55f..5c9890d 100644 --- a/include/qemu/int128.h +++ b/include/qemu/int128.h @@ -4,7 +4,7 @@ #ifdef CONFIG_INT128 #include "qemu/bswap.h" -typedef __int128 Int128; +typedef __int128_t Int128; static inline Int128 int128_make64(uint64_t a) { @@ -13,7 +13,7 @@ static inline Int128 int128_make64(uint64_t a) static inline Int128 int128_make128(uint64_t lo, uint64_t hi) { -return (unsigned __int128)hi << 64 | lo; +return (__uint128_t)hi << 64 | lo; }
Re: [Qemu-devel] [PATCH v2] target-mips: generate fences
On Thu, Sep 08, 2016 at 10:04:05AM -0700, Richard Henderson wrote: > > +static void gen_sync(int stype) > > +{ > > +TCGOrder tcg_mo = TCG_BAR_SC; > > + > > +switch (stype) { > > +case 0x4: /* SYNC_WMB */ > > +tcg_mo |= TCG_MO_ST_ST; > > +break; > > +case 0x10: /* SYNC_MB */ > > +tcg_mo |= TCG_MO_ALL; > > +break; > > +case 0x11: /* SYNC_ACQUIRE */ > > +tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST; > > +break; > > +case 0x12: /* SYNC_RELEASE */ > > +tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST; > > +break; > > +case 0x13: /* SYNC_RMB */ > > +tcg_mo |= TCG_MO_LD_LD; > > +break; > > +default: > > +tcg_mo |= TCG_MO_ALL; > > +break; > > +} > > See git://github.com/rth7680/qemu.git tcg-next wherein this suggests that some > enhancement is desired in tcg/mips/ as well. Not that I have a mips32r6 board > with which to test. Would you or James Hogan be able to improve that? Actually the lightweight variants of SYNC exist also in earlier revisions of MIPS architecture; therefore this can be tested for example on mips32r2. According to manuals the support is optional, and if given CPU doesn't implement lightweight SYNCs (i.e. with stype != 0) then they are supposed to behave in the same way as SYNC 0. (which also means I simplified that here and always interpret the stype to take advantage of weaker ordering barriers). Thanks, Leon
Re: [Qemu-devel] [PATCH v4 2/5] linux-user: Fix TARGET_F_GETOWN definition for Mips
On Mon, Sep 05, 2016 at 04:02:05PM +0200, Aleksandar Markovic wrote: > From: Aleksandar Markovic > > For some reason, Qemu's TARGET_F_GETOWN constant for Mips does not > match the correct value of correspondant F_GETOWN. This patch fixes > this problem. > > For reference, see Mips' F_GETOWN definition in Linux kernel at > arch/mips/include/uapi/asm/fcntl.h#L44. > > This patch also fixes some fcntl()-related LTP tests for Qemu > user mode for Mips. > > Signed-off-by: Miodrag Dinic Hi Aleksandar, Since you're submitting the patch you need to add also your Signed-off-by: line here (similarly in other patches in the series). Thanks, Leon > --- > linux-user/syscall_defs.h |2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h > index e6171ae..27d93a8 100644 > --- a/linux-user/syscall_defs.h > +++ b/linux-user/syscall_defs.h > @@ -2186,7 +2186,7 @@ struct target_statfs64 { > #define TARGET_F_SETLK 6 > #define TARGET_F_SETLKW7 > #define TARGET_F_SETOWN24 /* for sockets. */ > -#define TARGET_F_GETOWN25 /* for sockets. */ > +#define TARGET_F_GETOWN23 /* for sockets. */ > #else > #define TARGET_F_GETLK 5 > #define TARGET_F_SETLK 6 > -- > 1.7.9.5 >
Re: [Qemu-devel] [PATCH 0/7] MIPS Boston board support
On Thu, Sep 08, 2016 at 11:46:38AM +0100, Paul Burton wrote: > On 08/09/16 09:57, Leon Alrae wrote: > > On Fri, Aug 19, 2016 at 08:40:32PM +0100, Paul Burton wrote: > >> On 19/08/16 20:25, no-re...@patchew.org wrote: > >>> Hi, > >>> > >>> Your series failed automatic build test. Please find the testing commands > >>> and > >>> their output below. If you have docker installed, you can probably > >>> reproduce it > >>> locally. > >>> > >>> Message-id: 20160819190903.10974-1-paul.bur...@imgtec.com > >>> Subject: [Qemu-devel] [PATCH 0/7] MIPS Boston board support > >>> Type: series > >> > >> FYI, this build failure occurs because dtc/libfdt is missing this commit: > >> > >> > >> https://git.kernel.org/cgit/utils/dtc/dtc.git/commit/libfdt/version.lds?id=a4b093f7366fdb429ca1781144d3985fa50d0fbb > >> > >> Unfortunately the last release of dtc seems to be very old despite there > >> being fixes like that present in it for well over a year. I'm open to > >> suggestions about how to handle that... > > > > Looks like 1.4.2 has appeared recently and it contains above commit. > > Hi Leon, > > Great - that's good timing! :) > > > > > One way would be just to bump our minimal dtc version requirement from > > 1.4.0 to 1.4.2 (and update qemu's dtc submodule as well)... > > Would you like me to submit a v2 which does that & removes the > extraneous semicolon from patch 1? Yes, that would be good. Thanks, Leon
[Qemu-devel] [PATCH v2] target-mips: generate fences
Make use of memory barrier TCG opcode in MIPS front end. Signed-off-by: Leon Alrae --- v2: * generate weaker barriers according to stype --- target-mips/translate.c | 32 ++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index c212e4f..1e66274 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -13109,6 +13109,34 @@ static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd, tcg_temp_free(t1); } +static void gen_sync(int stype) +{ +TCGOrder tcg_mo = TCG_BAR_SC; + +switch (stype) { +case 0x4: /* SYNC_WMB */ +tcg_mo |= TCG_MO_ST_ST; +break; +case 0x10: /* SYNC_MB */ +tcg_mo |= TCG_MO_ALL; +break; +case 0x11: /* SYNC_ACQUIRE */ +tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST; +break; +case 0x12: /* SYNC_RELEASE */ +tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST; +break; +case 0x13: /* SYNC_RMB */ +tcg_mo |= TCG_MO_LD_LD; +break; +default: +tcg_mo |= TCG_MO_ALL; +break; +} + +tcg_gen_mb(tcg_mo); +} + static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs) { int extension = (ctx->opcode >> 6) & 0x3f; @@ -13384,7 +13412,7 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs) case 0x2d: switch (minor) { case SYNC: -/* NOP */ +gen_sync(extract32(ctx->opcode, 16, 5)); break; case SYSCALL: generate_exception_end(ctx, EXCP_SYSCALL); @@ -17201,7 +17229,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) break; case OPC_SYNC: check_insn(ctx, ISA_MIPS2); -/* Treat as NOP. */ +gen_sync(extract32(ctx->opcode, 6, 5)); break; #if defined(TARGET_MIPS64) -- 2.7.4
Re: [Qemu-devel] [PATCH 0/7] MIPS Boston board support
On Fri, Aug 19, 2016 at 08:40:32PM +0100, Paul Burton wrote: > On 19/08/16 20:25, no-re...@patchew.org wrote: > > Hi, > > > > Your series failed automatic build test. Please find the testing commands > > and > > their output below. If you have docker installed, you can probably > > reproduce it > > locally. > > > > Message-id: 20160819190903.10974-1-paul.bur...@imgtec.com > > Subject: [Qemu-devel] [PATCH 0/7] MIPS Boston board support > > Type: series > > FYI, this build failure occurs because dtc/libfdt is missing this commit: > > > https://git.kernel.org/cgit/utils/dtc/dtc.git/commit/libfdt/version.lds?id=a4b093f7366fdb429ca1781144d3985fa50d0fbb > > Unfortunately the last release of dtc seems to be very old despite there > being fixes like that present in it for well over a year. I'm open to > suggestions about how to handle that... Looks like 1.4.2 has appeared recently and it contains above commit. One way would be just to bump our minimal dtc version requirement from 1.4.0 to 1.4.2 (and update qemu's dtc submodule as well)... Thanks, Leon > > Thanks, > Paul > > > > > === TEST SCRIPT BEGIN === > > #!/bin/bash > > set -e > > git submodule update --init dtc > > make J=8 docker-test-quick@centos6 > > > > # we need CURL DPRINTF patch > > # > > http://patchew.org/QEMU/1470027888-24381-1-git-send-email-famz%40redhat.com/ > > #make J=8 docker-test-mingw@fedora > > === TEST SCRIPT END === > > > > Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384 > > Switched to a new branch 'test' > > 1821581 hw/mips: MIPS Boston board support > > 9b44da9 hw: xilinx-pcie: Add support for Xilinx AXI PCIe Controller > > fe513d4 loader: Support Flattened Image Trees (FIT images) > > d0296cc target-mips: Provide function to test if a CPU supports an ISA > > 52c4cc5 hw/mips_gic: Update pin state on mask changes > > 402000d hw/mips_gictimer: provide API for retrieving frequency > > a80d326 hw/mips_cmgcr: allow GCR base to be moved > > > > === OUTPUT BEGIN === > > Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path > > 'dtc' > > Cloning into 'dtc'... > > Submodule path 'dtc': checked out '65cc4d2748a2c2e6f27f1cf39e07a5dbabd80ebf' > > BUILD centos6 > > ARCHIVE qemu.tgz > > ARCHIVE dtc.tgz > > COPY RUNNER > > RUN test-quick in centos6 > > No C++ compiler available; disabling C++ specific optional code > > Install prefix/tmp/qemu-test/src/tests/docker/install > > BIOS directory/tmp/qemu-test/src/tests/docker/install/share/qemu > > binary directory /tmp/qemu-test/src/tests/docker/install/bin > > library directory /tmp/qemu-test/src/tests/docker/install/lib > > module directory /tmp/qemu-test/src/tests/docker/install/lib/qemu > > libexec directory /tmp/qemu-test/src/tests/docker/install/libexec > > include directory /tmp/qemu-test/src/tests/docker/install/include > > config directory /tmp/qemu-test/src/tests/docker/install/etc > > local state directory /tmp/qemu-test/src/tests/docker/install/var > > Manual directory /tmp/qemu-test/src/tests/docker/install/share/man > > ELF interp prefix /usr/gnemul/qemu-%M > > Source path /tmp/qemu-test/src > > C compilercc > > Host C compiler cc > > C++ compiler > > Objective-C compiler cc > > ARFLAGS rv > > CFLAGS-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -pthread > > -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -g > > QEMU_CFLAGS -I/usr/include/pixman-1-fPIE -DPIE -m64 -D_GNU_SOURCE > > -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes > > -Wredundant-decls -Wall -Wundef -Wwrite-strings -Wmissing-prototypes > > -fno-strict-aliasing -fno-common -Wendif-labels -Wmissing-include-dirs > > -Wempty-body -Wnested-externs -Wformat-security -Wformat-y2k -Winit-self > > -Wignored-qualifiers -Wold-style-declaration -Wold-style-definition > > -Wtype-limits -fstack-protector-all > > LDFLAGS -Wl,--warn-common -Wl,-z,relro -Wl,-z,now -pie -m64 -g > > make make > > install install > > pythonpython -B > > smbd /usr/sbin/smbd > > module supportno > > host CPU x86_64 > > host big endian no > > target list x86_64-softmmu aarch64-softmmu > > tcg debug enabled no > > gprof enabled no > > sparse enabledno > > strip binariesyes > > profiler no > > static build no > > pixmansystem > > SDL support yes (1.2.14) > > GTK support no > > GTK GL supportno > > VTE support no > > TLS priority NORMAL > > GNUTLS supportno > > GNUTLS rndno > > libgcrypt no > > libgcrypt kdf no > > nettleno > > nettle kdfno > > libtasn1 no > > curses supportno > > virgl support no > > curl support no > > mingw32 support no > > Audio drivers oss > > Block whitelist (rw) > > Block whitelist (ro) > > VirtFS supportno > > VNC support yes > > VNC SASL support no > > VNC JPEG suppo
[Qemu-devel] [PATCH] target-mips: generate fences
Make use of memory barrier TCG opcode in MIPS front end. Signed-off-by: Leon Alrae --- This patch complements the following series: https://lists.nongnu.org/archive/html/qemu-devel/2016-07/msg03283.html --- target-mips/translate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index c212e4f..f4513bf 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -13384,7 +13384,7 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs) case 0x2d: switch (minor) { case SYNC: -/* NOP */ +tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC); break; case SYSCALL: generate_exception_end(ctx, EXCP_SYSCALL); @@ -17201,7 +17201,7 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) break; case OPC_SYNC: check_insn(ctx, ISA_MIPS2); -/* Treat as NOP. */ +tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC); break; #if defined(TARGET_MIPS64) -- 2.7.4
Re: [Qemu-devel] [PATCH 4/7] target-mips: Provide function to test if a CPU supports an ISA
On Fri, Aug 19, 2016 at 08:09:00PM +0100, Paul Burton wrote: > Provide a new cpu_supports_isa function which allows callers to > determine whether a CPU supports one of the ISA_ flags, by testing > whether the associated struct mips_def_t sets the ISA flags in its > insn_flags field. > > An example use of this is to allow boards which generate bootloader code > to determine the properties of the CPU that will be used, for example > whether the CPU is 64 bit or which architecture revision it implements. > > Signed-off-by: Paul Burton > --- > target-mips/cpu.h | 1 + > target-mips/translate.c | 10 ++ > 2 files changed, 11 insertions(+) Reviewed-by: Leon Alrae
Re: [Qemu-devel] [PATCH 3/7] hw/mips_gic: Update pin state on mask changes
On Fri, Aug 19, 2016 at 08:08:59PM +0100, Paul Burton wrote: > If the GIC interrupt mask is changed by a write to the smask (set mask) > or rmask (reset mask) registers, we need to re-evaluate the state of the > pins/IRQs fed to the CPU. Without doing so we risk leaving a pin high > despite the interrupt that led to that state being masked, or losing > interrupts if an already pending interrupt is unmasked. > > Signed-off-by: Paul Burton > --- > hw/intc/mips_gic.c | 56 > ++ > 1 file changed, 31 insertions(+), 25 deletions(-) Reviewed-by: Leon Alrae
Re: [Qemu-devel] [PATCH 2/7] hw/mips_gictimer: provide API for retrieving frequency
On Fri, Aug 19, 2016 at 08:08:58PM +0100, Paul Burton wrote: > Provide a new function mips_gictimer_get_freq() which returns the > frequency at which a GIC timer will count. This will be useful for > boards which perform setup based upon this frequency. > > Signed-off-by: Paul Burton > --- > hw/timer/mips_gictimer.c | 5 + > include/hw/timer/mips_gictimer.h | 1 + > 2 files changed, 6 insertions(+) Reviewed-by: Leon Alrae
Re: [Qemu-devel] [PATCH 1/7] hw/mips_cmgcr: allow GCR base to be moved
On Fri, Aug 19, 2016 at 08:08:57PM +0100, Paul Burton wrote: > Support moving the GCR base address & updating the CPU's CP0 CMGCRBase > register appropriately. This is required if a platform needs to move its > GCRs away from other memory, as the MIPS Boston development board does > to avoid its flash memory. > > Signed-off-by: Paul Burton > --- > hw/misc/mips_cmgcr.c | 17 + > include/hw/misc/mips_cmgcr.h | 3 +++ > 2 files changed, 20 insertions(+) > > diff --git a/hw/misc/mips_cmgcr.c b/hw/misc/mips_cmgcr.c > index b3ba166..a1edb53 100644 > --- a/hw/misc/mips_cmgcr.c > +++ b/hw/misc/mips_cmgcr.c > @@ -29,6 +29,20 @@ static inline bool is_gic_connected(MIPSGCRState *s) > return s->gic_mr != NULL; > } > > +static inline void update_gcr_base(MIPSGCRState *gcr, uint64_t val) > +{ > +CPUState *cpu; > +MIPSCPU *mips_cpu; > + > +gcr->gcr_base = val & GCR_BASE_GCRBASE_MSK; > +memory_region_set_address(&gcr->iomem, gcr->gcr_base); > + > +CPU_FOREACH(cpu) { > +mips_cpu = MIPS_CPU(cpu); > +mips_cpu->env.CP0_CMGCRBase = gcr->gcr_base >> 4; > +} > +} > + > static inline void update_cpc_base(MIPSGCRState *gcr, uint64_t val) > { > if (is_cpc_connected(gcr)) { > @@ -117,6 +131,9 @@ static void gcr_write(void *opaque, hwaddr addr, uint64_t > data, unsigned size) > MIPSGCRVPState *other_vps = &gcr->vps[current_vps->other]; > > switch (addr) { > +case GCR_BASE_OFS: > +update_gcr_base(gcr, data); > +break; > case GCR_GIC_BASE_OFS: > update_gic_base(gcr, data); > break; > diff --git a/include/hw/misc/mips_cmgcr.h b/include/hw/misc/mips_cmgcr.h > index a209d91..31bda6a 100644 > --- a/include/hw/misc/mips_cmgcr.h > +++ b/include/hw/misc/mips_cmgcr.h > @@ -41,6 +41,9 @@ > #define GCR_L2_CONFIG_BYPASS_SHF20 > #define GCR_L2_CONFIG_BYPASS_MSK((0x1ULL) << GCR_L2_CONFIG_BYPASS_SHF) > > +/* GCR_BASE register fields */ > +#define GCR_BASE_GCRBASE_MSK 0x8000ULL; Unnecessary semicolon? Otherwise Reviewed-by: Leon Alrae
[Qemu-devel] [PULL 2/2] target-mips: fix EntryHi.EHINV being cleared on TLB exception
While implementing TLB invalidation feature we forgot to modify part of code responsible for updating EntryHi during TLB exception. Consequently EntryHi.EHINV is unexpectedly cleared on the exception. Signed-off-by: Leon Alrae --- target-mips/helper.c | 1 + 1 file changed, 1 insertion(+) diff --git a/target-mips/helper.c b/target-mips/helper.c index 9fbca26..c864b15 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -396,6 +396,7 @@ static void raise_mmu_exception(CPUMIPSState *env, target_ulong address, env->CP0_Context = (env->CP0_Context & ~0x007f) | ((address >> 9) & 0x0070); env->CP0_EntryHi = (env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask) | + (env->CP0_EntryHi & (1 << CP0EnHi_EHINV)) | (address & (TARGET_PAGE_MASK << 1)); #if defined(TARGET_MIPS64) env->CP0_EntryHi &= env->SEGMask; -- 2.7.4
[Qemu-devel] [PULL 0/2] target-mips queue
Hi, Just a couple of bug fixes for rc1. Thanks, Leon Cc: Peter Maydell Cc: Aurelien Jarno The following changes since commit 21a21b853a1bb606358af61e738abfb9aecbd720: Merge remote-tracking branch 'remotes/ehabkost/tags/x86-pull-request' into staging (2016-07-27 18:18:21 +0100) are available in the git repository at: git://github.com/lalrae/qemu.git tags/mips-20160729 for you to fetch changes up to 701074a6fc7470d0ed54e4a4bcd4d491ad8da22e: target-mips: fix EntryHi.EHINV being cleared on TLB exception (2016-07-28 11:24:02 +0100) MIPS patches 2016-07-29 Changes: * bug fixes ---- Leon Alrae (1): target-mips: fix EntryHi.EHINV being cleared on TLB exception Paul Burton (1): hw/mips_malta: Fix YAMON API print routine hw/mips/mips_malta.c | 2 +- target-mips/helper.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-)
[Qemu-devel] [PULL 1/2] hw/mips_malta: Fix YAMON API print routine
From: Paul Burton The print routine provided as part of the in-built bootloader had a bug in that it attempted to use a jump instruction as part of a loop, but the target has its upper bits zeroed leading to control flow transferring to 0xb814 rather than the intended 0xbfc00814. Fix this by using a branch instruction instead, which seems more fit for purpose. A simple way to test this is to build a Linux kernel with EVA enabled & attempt to boot it in QEMU. It will attempt to print a message indicating the configuration mismatch but QEMU would previously incorrectly jump & wind up printing a continuous stream of the letter E. Signed-off-by: Paul Burton Cc: Aurelien Jarno Cc: Leon Alrae Reviewed-by: Aurelien Jarno Reviewed-by: Leon Alrae Signed-off-by: Leon Alrae --- hw/mips/mips_malta.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index 34d41ef..e90857e 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -727,7 +727,7 @@ static void write_bootloader(uint8_t *base, int64_t run_addr, stl_p(p++, 0x); /* nop */ stl_p(p++, 0x0ff0021c); /* jal 870 */ stl_p(p++, 0x); /* nop */ -stl_p(p++, 0x08000205); /* j 814 */ +stl_p(p++, 0x1000fff9); /* b 814 */ stl_p(p++, 0x); /* nop */ stl_p(p++, 0x01a9); /* jalr t5 */ stl_p(p++, 0x01602021); /* move a0,t3 */ -- 2.7.4
[Qemu-devel] [PATCH] target-mips: fix EntryHi.EHINV being cleared on TLB exception
While implementing TLB invalidation feature we forgot to modify part of code responsible for updating EntryHi during TLB exception. Consequently EntryHi.EHINV is unexpectedly cleared on the exception. Signed-off-by: Leon Alrae --- target-mips/helper.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/target-mips/helper.c b/target-mips/helper.c index 9fbca26..c864b15 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -396,6 +396,7 @@ static void raise_mmu_exception(CPUMIPSState *env, target_ulong address, env->CP0_Context = (env->CP0_Context & ~0x007f) | ((address >> 9) & 0x0070); env->CP0_EntryHi = (env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask) | + (env->CP0_EntryHi & (1 << CP0EnHi_EHINV)) | (address & (TARGET_PAGE_MASK << 1)); #if defined(TARGET_MIPS64) env->CP0_EntryHi &= env->SEGMask; -- 1.7.1
Re: [Qemu-devel] [PATCH] tcg: Merge GETPC and GETRA
On Tue, Jul 26, 2016 at 06:12:40AM +0530, Richard Henderson wrote: > The return address argument to the softmmu template helpers was > confused. In the legacy case, we wanted to indicate that there > is no return address, and so passed in NULL. However, we then > immediately subtracted GETPC_ADJ from NULL, resulting in a non-zero > value, indicating the presence of an (invalid) return address. > > Push the GETPC_ADJ subtraction down to the only point it's required: > immediately before use within cpu_restore_state, after all NULL pointer > checks have been completed. This makes GETPC and GETRA identical. > > Remove GETRA as the lesser used macro, replacing all uses with GETPC. > > Signed-off-by: Richard Henderson > --- > > Ben, this should fix the "-2" problem that you reported. Of course, > as also discussed in that thread, this won't fix the whole issue. > > > r~ > > --- > cputlb.c| 6 ++ > include/exec/exec-all.h | 9 +++-- > softmmu_template.h | 32 ++-- > target-arm/helper.c | 6 +++--- > target-mips/op_helper.c | 18 +- > translate-all.c | 1 + > 6 files changed, 24 insertions(+), 48 deletions(-) Looks good to me: Reviewed-by: Leon Alrae Thanks, Leon
Re: [Qemu-devel] [PATCH] target-mips: add 24KEc CPU definition
On Tue, Jul 26, 2016 at 12:42:45AM +0100, André Draszik wrote: > Define a new CPU definition supporting 24KEc cores, similar to > the existing 24Kc, but with added support for DSP instructions > and MIPS16e (and without FPU). > > Signed-off-by: André Draszik > --- > target-mips/translate_init.c | 22 ++ > 1 file changed, 22 insertions(+) Thanks for the patch. We are currently in hard feature freeze and we are merging bug-fixes only, so I applied it to the post-v2.7 target-mips queue. Leon
Re: [Qemu-devel] [PATCH] hw/mips_malta: Fix YAMON API print routine
On Fri, Jul 22, 2016 at 10:55:40AM +0100, Paul Burton wrote: > The print routine provided as part of the in-built bootloader had a bug > in that it attempted to use a jump instruction as part of a loop, but > the target has its upper bits zeroed leading to control flow > transferring to 0xb814 rather than the intended 0xbfc00814. Fix this > by using a branch instruction instead, which seems more fit for purpose. > > A simple way to test this is to build a Linux kernel with EVA enabled & > attempt to boot it in QEMU. It will attempt to print a message > indicating the configuration mismatch but QEMU would previously > incorrectly jump & wind up printing a continuous stream of the letter E. > > Signed-off-by: Paul Burton > Cc: Aurelien Jarno > Cc: Leon Alrae > --- > hw/mips/mips_malta.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) Applied to target-mips queue. Thanks, Leon
Re: [Qemu-devel] [PATCH 3/7] hw/mips: fix PCI bus initialization
On Thu, Jul 14, 2016 at 04:43:42PM +0300, Marcel Apfelbaum wrote: > Delay the host-bridge 'realization' until the > PCI root bus is attached. > > Signed-off-by: Marcel Apfelbaum > --- > hw/mips/gt64xxx_pci.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) Acked-by: Leon Alrae Tested-by: Leon Alrae Thanks, Leon > > diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c > index 3f4523d..4811843 100644 > --- a/hw/mips/gt64xxx_pci.c > +++ b/hw/mips/gt64xxx_pci.c > @@ -1167,7 +1167,6 @@ PCIBus *gt64120_register(qemu_irq *pic) > DeviceState *dev; > > dev = qdev_create(NULL, TYPE_GT64120_PCI_HOST_BRIDGE); > -qdev_init_nofail(dev); > d = GT64120_PCI_HOST_BRIDGE(dev); > phb = PCI_HOST_BRIDGE(dev); > memory_region_init(&d->pci0_mem, OBJECT(dev), "pci0-mem", UINT32_MAX); > @@ -1178,6 +1177,7 @@ PCIBus *gt64120_register(qemu_irq *pic) > &d->pci0_mem, > get_system_io(), > PCI_DEVFN(18, 0), 4, TYPE_PCI_BUS); > +qdev_init_nofail(dev); > memory_region_init_io(&d->ISD_mem, OBJECT(dev), &isd_mem_ops, d, > "isd-mem", 0x1000); > > pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "gt64120_pci"); > -- > 2.4.3 >
[Qemu-devel] [PULL 08/11] target-mips: add ASID mask field and replace magic values
From: Paul Burton Signed-off-by: Paul Burton Signed-off-by: James Hogan Signed-off-by: Leon Alrae --- target-mips/cpu.h | 2 ++ target-mips/helper.c| 10 +- target-mips/op_helper.c | 27 +++ target-mips/translate.c | 1 + 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/target-mips/cpu.h b/target-mips/cpu.h index fe1c4b8..6325e15 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -343,6 +343,7 @@ struct CPUMIPSState { int32_t CP0_Count; target_ulong CP0_EntryHi; #define CP0EnHi_EHINV 10 +target_ulong CP0_EntryHi_ASID_mask; int32_t CP0_Compare; int32_t CP0_Status; #define CP0St_CU3 31 @@ -503,6 +504,7 @@ struct CPUMIPSState { int CP0_LLAddr_shift; target_ulong CP0_WatchLo[8]; int32_t CP0_WatchHi[8]; +#define CP0WH_ASID 16 target_ulong CP0_XContext; int32_t CP0_Framemask; int32_t CP0_Debug; diff --git a/target-mips/helper.c b/target-mips/helper.c index 1402ff0..1e194e9 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -67,7 +67,7 @@ int fixed_mmu_map_address (CPUMIPSState *env, hwaddr *physical, int *prot, int r4k_map_address (CPUMIPSState *env, hwaddr *physical, int *prot, target_ulong address, int rw, int access_type) { -uint8_t ASID = env->CP0_EntryHi & 0xFF; +uint8_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; int i; for (i = 0; i < env->tlb->tlb_in_use; i++) { @@ -249,7 +249,7 @@ void sync_c0_status(CPUMIPSState *env, CPUMIPSState *cpu, int tc) cu = (v >> CP0St_CU0) & 0xf; mx = (v >> CP0St_MX) & 0x1; ksu = (v >> CP0St_KSU) & 0x3; -asid = env->CP0_EntryHi & 0xff; +asid = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; tcstatus = cu << CP0TCSt_TCU0; tcstatus |= mx << CP0TCSt_TMX; @@ -395,8 +395,8 @@ static void raise_mmu_exception(CPUMIPSState *env, target_ulong address, env->CP0_BadVAddr = address; env->CP0_Context = (env->CP0_Context & ~0x007f) | ((address >> 9) & 0x0070); -env->CP0_EntryHi = -(env->CP0_EntryHi & 0xFF) | (address & (TARGET_PAGE_MASK << 1)); +env->CP0_EntryHi = (env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask) | + (address & (TARGET_PAGE_MASK << 1)); #if defined(TARGET_MIPS64) env->CP0_EntryHi &= env->SEGMask; env->CP0_XContext = @@ -898,7 +898,7 @@ void r4k_invalidate_tlb (CPUMIPSState *env, int idx, int use_extra) r4k_tlb_t *tlb; target_ulong addr; target_ulong end; -uint8_t ASID = env->CP0_EntryHi & 0xFF; +uint8_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; target_ulong mask; tlb = &env->tlb->mmu.r4k.tlb[idx]; diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 69daade..1562f22 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -679,7 +679,7 @@ static void sync_c0_tcstatus(CPUMIPSState *cpu, int tc, tcu = (v >> CP0TCSt_TCU0) & 0xf; tmx = (v >> CP0TCSt_TMX) & 0x1; -tasid = v & 0xff; +tasid = v & cpu->CP0_EntryHi_ASID_mask; tksu = (v >> CP0TCSt_TKSU) & 0x3; status = tcu << CP0St_CU0; @@ -690,7 +690,7 @@ static void sync_c0_tcstatus(CPUMIPSState *cpu, int tc, cpu->CP0_Status |= status; /* Sync the TASID with EntryHi. */ -cpu->CP0_EntryHi &= ~0xff; +cpu->CP0_EntryHi &= ~cpu->CP0_EntryHi_ASID_mask; cpu->CP0_EntryHi |= tasid; compute_hflags(cpu); @@ -702,7 +702,7 @@ static void sync_c0_entryhi(CPUMIPSState *cpu, int tc) int32_t *tcst; uint32_t asid, v = cpu->CP0_EntryHi; -asid = v & 0xff; +asid = v & cpu->CP0_EntryHi_ASID_mask; if (tc == cpu->current_tc) { tcst = &cpu->active_tc.CP0_TCStatus; @@ -710,7 +710,7 @@ static void sync_c0_entryhi(CPUMIPSState *cpu, int tc) tcst = &cpu->tcs[tc].CP0_TCStatus; } -*tcst &= ~0xff; +*tcst &= ~cpu->CP0_EntryHi_ASID_mask; *tcst |= asid; } @@ -1403,7 +1403,7 @@ void helper_mtc0_count(CPUMIPSState *env, target_ulong arg1) void helper_mtc0_entryhi(CPUMIPSState *env, target_ulong arg1) { target_ulong old, val, mask; -mask = (TARGET_PAGE_MASK << 1) | 0xFF; +mask = (TARGET_PAGE_MASK << 1) | env->CP0_EntryHi_ASID_mask; if (((env->CP0_Config4 >> CP0C4_IE) & 0x3) >= 2) { mask |= 1 << CP0EnHi_EHINV; } @@ -1429,8 +1429,10 @@ void helper_mtc0_entryhi(CPUMIPSState *env, target_ulong arg1) sync_c0_entryhi(env, env->current_tc); } /* If the ASID changes, flush qemu's TLB. */ -if ((old & 0xFF) != (val & 0xFF)) +if ((old &a
[Qemu-devel] [PULL 09/11] target-mips: change ASID type to hold more than 8 bits
From: Paul Burton ASID currently has uint8_t type which is too small since some processors support more than 8 bits ASID. Therefore change its type to uint16_t. Signed-off-by: Paul Burton Signed-off-by: James Hogan Signed-off-by: Leon Alrae --- target-mips/cpu.h | 2 +- target-mips/helper.c| 4 ++-- target-mips/machine.c | 10 +- target-mips/op_helper.c | 8 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 6325e15..3e233ad 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -19,7 +19,7 @@ typedef struct r4k_tlb_t r4k_tlb_t; struct r4k_tlb_t { target_ulong VPN; uint32_t PageMask; -uint8_t ASID; +uint16_t ASID; unsigned int G:1; unsigned int C0:3; unsigned int C1:3; diff --git a/target-mips/helper.c b/target-mips/helper.c index 1e194e9..9fbca26 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -67,7 +67,7 @@ int fixed_mmu_map_address (CPUMIPSState *env, hwaddr *physical, int *prot, int r4k_map_address (CPUMIPSState *env, hwaddr *physical, int *prot, target_ulong address, int rw, int access_type) { -uint8_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; +uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; int i; for (i = 0; i < env->tlb->tlb_in_use; i++) { @@ -898,7 +898,7 @@ void r4k_invalidate_tlb (CPUMIPSState *env, int idx, int use_extra) r4k_tlb_t *tlb; target_ulong addr; target_ulong end; -uint8_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; +uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; target_ulong mask; tlb = &env->tlb->mmu.r4k.tlb[idx]; diff --git a/target-mips/machine.c b/target-mips/machine.c index 7314cfe..a27f2f1 100644 --- a/target-mips/machine.c +++ b/target-mips/machine.c @@ -132,7 +132,7 @@ static int get_tlb(QEMUFile *f, void *pv, size_t size) qemu_get_betls(f, &v->VPN); qemu_get_be32s(f, &v->PageMask); -qemu_get_8s(f, &v->ASID); +qemu_get_be16s(f, &v->ASID); qemu_get_be16s(f, &flags); v->G = (flags >> 10) & 1; v->C0 = (flags >> 7) & 3; @@ -156,7 +156,7 @@ static void put_tlb(QEMUFile *f, void *pv, size_t size) { r4k_tlb_t *v = pv; -uint8_t asid = v->ASID; +uint16_t asid = v->ASID; uint16_t flags = ((v->EHINV << 15) | (v->RI1 << 14) | (v->RI0 << 13) | @@ -172,7 +172,7 @@ static void put_tlb(QEMUFile *f, void *pv, size_t size) qemu_put_betls(f, &v->VPN); qemu_put_be32s(f, &v->PageMask); -qemu_put_8s(f, &asid); +qemu_put_be16s(f, &asid); qemu_put_be16s(f, &flags); qemu_put_be64s(f, &v->PFN[0]); qemu_put_be64s(f, &v->PFN[1]); @@ -192,8 +192,8 @@ const VMStateInfo vmstate_info_tlb = { const VMStateDescription vmstate_tlb = { .name = "cpu/tlb", -.version_id = 1, -.minimum_version_id = 1, +.version_id = 2, +.minimum_version_id = 2, .fields = (VMStateField[]) { VMSTATE_UINT32(nb_tlb, CPUMIPSTLBContext), VMSTATE_UINT32(tlb_in_use, CPUMIPSTLBContext), diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 1562f22..31c85f9 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -2013,7 +2013,7 @@ void r4k_helper_tlbinv(CPUMIPSState *env) { int idx; r4k_tlb_t *tlb; -uint8_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; +uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; for (idx = 0; idx < env->tlb->nb_tlb; idx++) { tlb = &env->tlb->mmu.r4k.tlb[idx]; @@ -2039,7 +2039,7 @@ void r4k_helper_tlbwi(CPUMIPSState *env) r4k_tlb_t *tlb; int idx; target_ulong VPN; -uint8_t ASID; +uint16_t ASID; bool G, V0, D0, V1, D1; idx = (env->CP0_Index & ~0x8000) % env->tlb->nb_tlb; @@ -2081,7 +2081,7 @@ void r4k_helper_tlbp(CPUMIPSState *env) target_ulong mask; target_ulong tag; target_ulong VPN; -uint8_t ASID; +uint16_t ASID; int i; ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; @@ -2136,7 +2136,7 @@ static inline uint64_t get_entrylo_pfn_from_tlb(uint64_t tlb_pfn) void r4k_helper_tlbr(CPUMIPSState *env) { r4k_tlb_t *tlb; -uint8_t ASID; +uint16_t ASID; int idx; ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; -- 2.7.4
[Qemu-devel] [PULL 11/11] target-mips: enable 10-bit ASIDs in I6400 CPU
Signed-off-by: Leon Alrae --- target-mips/translate_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c index c43bdb7..39ed5c4 100644 --- a/target-mips/translate_init.c +++ b/target-mips/translate_init.c @@ -685,7 +685,7 @@ static const mips_def_t mips_defs[] = (1 << CP0C3_BP) | (1 << CP0C3_BI) | (1 << CP0C3_ULRI) | (1 << CP0C3_RXI) | (1 << CP0C3_LPA) | (1 << CP0C3_VInt), .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) | (3 << CP0C4_IE) | - (0xfc << CP0C4_KScrExist), + (1 << CP0C4_AE) | (0xfc << CP0C4_KScrExist), .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_XNP) | (1 << CP0C5_VP) | (1 << CP0C5_LLB) | (1 << CP0C5_MRP), .CP0_Config5_rw_bitmask = (1 << CP0C5_MSAEn) | (1 << CP0C5_SBRI) | -- 2.7.4
[Qemu-devel] [PULL 06/11] hw/mips_cmgcr: implement RESET_BASE register in CM GCR
Implement RESET_BASE register which is local to each VP and a write to it changes VP's reset exception base. Also, add OTHER register to allow a software running on one VP to access other VP's local registers. Guest can use this mechanism to specify custom address from which a VP will start execution. Signed-off-by: Leon Alrae --- hw/misc/mips_cmgcr.c | 54 +++- include/hw/misc/mips_cmgcr.h | 18 +++ 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/hw/misc/mips_cmgcr.c b/hw/misc/mips_cmgcr.c index e6cf17d..b3ba166 100644 --- a/hw/misc/mips_cmgcr.c +++ b/hw/misc/mips_cmgcr.c @@ -59,6 +59,8 @@ static inline void update_gic_base(MIPSGCRState *gcr, uint64_t val) static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size) { MIPSGCRState *gcr = (MIPSGCRState *) opaque; +MIPSGCRVPState *current_vps = &gcr->vps[current_cpu->cpu_index]; +MIPSGCRVPState *other_vps = &gcr->vps[current_vps->other]; switch (addr) { /* Global Control Block Register */ @@ -85,8 +87,14 @@ static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size) case MIPS_COCB_OFS + GCR_CL_CONFIG_OFS: /* Set PVP to # of VPs - 1 */ return gcr->num_vps - 1; +case MIPS_CLCB_OFS + GCR_CL_RESETBASE_OFS: +return current_vps->reset_base; +case MIPS_COCB_OFS + GCR_CL_RESETBASE_OFS: +return other_vps->reset_base; case MIPS_CLCB_OFS + GCR_CL_OTHER_OFS: -return 0; +return current_vps->other; +case MIPS_COCB_OFS + GCR_CL_OTHER_OFS: +return other_vps->other; default: qemu_log_mask(LOG_UNIMP, "Read %d bytes at GCR offset 0x%" HWADDR_PRIx "\n", size, addr); @@ -95,10 +103,18 @@ static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size) return 0; } +static inline target_ulong get_exception_base(MIPSGCRVPState *vps) +{ +/* TODO: BEV_BASE and SELECT_BEV */ +return (int32_t)(vps->reset_base & GCR_CL_RESET_BASE_RESETBASE_MSK); +} + /* Write GCR registers */ static void gcr_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) { MIPSGCRState *gcr = (MIPSGCRState *)opaque; +MIPSGCRVPState *current_vps = &gcr->vps[current_cpu->cpu_index]; +MIPSGCRVPState *other_vps = &gcr->vps[current_vps->other]; switch (addr) { case GCR_GIC_BASE_OFS: @@ -107,6 +123,26 @@ static void gcr_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) case GCR_CPC_BASE_OFS: update_cpc_base(gcr, data); break; +case MIPS_CLCB_OFS + GCR_CL_RESETBASE_OFS: +current_vps->reset_base = data & GCR_CL_RESET_BASE_MSK; +cpu_set_exception_base(current_cpu->cpu_index, + get_exception_base(current_vps)); +break; +case MIPS_COCB_OFS + GCR_CL_RESETBASE_OFS: +other_vps->reset_base = data & GCR_CL_RESET_BASE_MSK; +cpu_set_exception_base(current_vps->other, + get_exception_base(other_vps)); +break; +case MIPS_CLCB_OFS + GCR_CL_OTHER_OFS: +if ((data & GCR_CL_OTHER_MSK) < gcr->num_vps) { +current_vps->other = data & GCR_CL_OTHER_MSK; +} +break; +case MIPS_COCB_OFS + GCR_CL_OTHER_OFS: +if ((data & GCR_CL_OTHER_MSK) < gcr->num_vps) { +other_vps->other = data & GCR_CL_OTHER_MSK; +} +break; default: qemu_log_mask(LOG_UNIMP, "Write %d bytes at GCR offset 0x%" HWADDR_PRIx " 0x%" PRIx64 "\n", size, addr, data); @@ -148,9 +184,16 @@ static void mips_gcr_init(Object *obj) static void mips_gcr_reset(DeviceState *dev) { MIPSGCRState *s = MIPS_GCR(dev); +int i; update_gic_base(s, 0); update_cpc_base(s, 0); + +for (i = 0; i < s->num_vps; i++) { +s->vps[i].other = 0; +s->vps[i].reset_base = 0xBFC0 & GCR_CL_RESET_BASE_MSK; +cpu_set_exception_base(i, get_exception_base(&s->vps[i])); +} } static const VMStateDescription vmstate_mips_gcr = { @@ -170,12 +213,21 @@ static Property mips_gcr_properties[] = { DEFINE_PROP_END_OF_LIST(), }; +static void mips_gcr_realize(DeviceState *dev, Error **errp) +{ +MIPSGCRState *s = MIPS_GCR(dev); + +/* Create local set of registers for each VP */ +s->vps = g_new(MIPSGCRVPState, s->num_vps); +} + static void mips_gcr_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->props = mips_gcr_properties; dc->vmsd = &vmstate_mips_gcr; dc->reset = mips_gcr_reset; +dc->realize = mips_gcr_realize; } static const TypeInfo mips_gcr_info = { diff --git a/include/hw/misc/mips_cmgcr.h b/include/hw/mi
[Qemu-devel] [PULL 01/11] hw/mips: implement GIC Interval Timer
From: Yongbok Kim The interval timer is similar to the CP0 Count/Compare timer within each processor. The difference is the GIC_SH_COUNTER register is global to the system so that all processors have the same time reference. To ease implementation, all VPs are having its own QEMU timer but sharing global settings and registers such as GIC_SH_CONFIG.COUTNSTOP and GIC_SH_COUNTER. MIPS GIC Interval Timer does support upto 64 bits of Count register but in this implementation it is limited to 32 bits only. Signed-off-by: Yongbok Kim Signed-off-by: Leon Alrae --- hw/timer/Makefile.objs | 1 + hw/timer/mips_gictimer.c | 142 +++ include/hw/timer/mips_gictimer.h | 46 + 3 files changed, 189 insertions(+) create mode 100644 hw/timer/mips_gictimer.c create mode 100644 include/hw/timer/mips_gictimer.h diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs index 003c14f..7ba8c23 100644 --- a/hw/timer/Makefile.objs +++ b/hw/timer/Makefile.objs @@ -26,6 +26,7 @@ obj-$(CONFIG_OMAP) += omap_synctimer.o obj-$(CONFIG_PXA2XX) += pxa2xx_timer.o obj-$(CONFIG_SH4) += sh_timer.o obj-$(CONFIG_DIGIC) += digic-timer.o +obj-$(CONFIG_MIPS_CPS) += mips_gictimer.o obj-$(CONFIG_MC146818RTC) += mc146818rtc.o diff --git a/hw/timer/mips_gictimer.c b/hw/timer/mips_gictimer.c new file mode 100644 index 000..3698889 --- /dev/null +++ b/hw/timer/mips_gictimer.c @@ -0,0 +1,142 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2016 Imagination Technologies + */ + +#include "qemu/osdep.h" +#include "hw/hw.h" +#include "hw/sysbus.h" +#include "qemu/timer.h" +#include "hw/timer/mips_gictimer.h" + +#define TIMER_PERIOD 10 /* 10 ns period for 100 Mhz frequency */ + +static void gic_vptimer_update(MIPSGICTimerState *gictimer, + uint32_t vp_index, uint64_t now) +{ +uint64_t next; +uint32_t wait; + +wait = gictimer->vptimers[vp_index].comparelo - gictimer->sh_counterlo - + (uint32_t)(now / TIMER_PERIOD); +next = now + (uint64_t)wait * TIMER_PERIOD; + +timer_mod(gictimer->vptimers[vp_index].qtimer, next); +} + +static void gic_vptimer_expire(MIPSGICTimerState *gictimer, uint32_t vp_index, + uint64_t now) +{ +if (gictimer->countstop) { +/* timer stopped */ +return; +} +gictimer->cb(gictimer->opaque, vp_index); +gic_vptimer_update(gictimer, vp_index, now); +} + +static void gic_vptimer_cb(void *opaque) +{ +MIPSGICTimerVPState *vptimer = opaque; +MIPSGICTimerState *gictimer = vptimer->gictimer; +gic_vptimer_expire(gictimer, vptimer->vp_index, + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); +} + +uint32_t mips_gictimer_get_sh_count(MIPSGICTimerState *gictimer) +{ +int i; +if (gictimer->countstop) { +return gictimer->sh_counterlo; +} else { +uint64_t now; +now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); +for (i = 0; i < gictimer->num_vps; i++) { +if (timer_pending(gictimer->vptimers[i].qtimer) +&& timer_expired(gictimer->vptimers[i].qtimer, now)) { +/* The timer has already expired. */ +gic_vptimer_expire(gictimer, i, now); +} +} +return gictimer->sh_counterlo + (uint32_t)(now / TIMER_PERIOD); +} +} + +void mips_gictimer_store_sh_count(MIPSGICTimerState *gictimer, uint64_t count) +{ +int i; +uint64_t now; + +if (gictimer->countstop || !gictimer->vptimers[0].qtimer) { +gictimer->sh_counterlo = count; +} else { +/* Store new count register */ +now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); +gictimer->sh_counterlo = count - (uint32_t)(now / TIMER_PERIOD); +/* Update timer timer */ +for (i = 0; i < gictimer->num_vps; i++) { +gic_vptimer_update(gictimer, i, now); +} +} +} + +uint32_t mips_gictimer_get_vp_compare(MIPSGICTimerState *gictimer, + uint32_t vp_index) +{ +return gictimer->vptimers[vp_index].comparelo; +} + +void mips_gictimer_store_vp_compare(MIPSGICTimerState *gictimer, +uint32_t vp_index, uint64_t compare) +{ +gictimer->vptimers[vp_index].comparelo = (uint32_t) compare; +gic_vptimer_update(gictimer, vp_index, + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); +} + +uint8_t mips_gictimer_get_countstop(MIPSGICTimerState *gictimer) +{ +return gictimer->countstop; +} + +void mips_gictimer_start_count(MIPSGICTimerState *gictimer) +{ +gictimer->countstop = 0; +mips_gictimer_store_sh_count(gi
[Qemu-devel] [PULL 02/11] hw/mips: implement Global Interrupt Controller
From: Yongbok Kim The Global Interrupt Controller (GIC) is responsible for mapping each internal and external interrupt to the correct location for servicing. The internal representation of registers is different from the specification in order to consolidate information for each GIC Interrupt Sources and Virtual Processors with same functionalities. For example SH_MAP00_VP00 registers are defined like each bit represents a VP but in this implementation the equivalent map_vp contains VP number in integer form for ease accesses. When it is being accessed via read write functions an internal data is converted back into the original format as the specification. Limitations: Level triggering only GIC CounterHi not implemented (Countbits = 32bits) DINT not implemented Local WatchDog, Fast Debug Channel, Perf Counter not implemented Signed-off-by: Yongbok Kim Signed-off-by: Leon Alrae --- hw/intc/Makefile.objs | 1 + hw/intc/mips_gic.c | 460 + include/hw/intc/mips_gic.h | 216 + 3 files changed, 677 insertions(+) create mode 100644 hw/intc/mips_gic.c create mode 100644 include/hw/intc/mips_gic.h diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs index 530df2e..05ec21b 100644 --- a/hw/intc/Makefile.objs +++ b/hw/intc/Makefile.objs @@ -37,3 +37,4 @@ obj-$(CONFIG_S390_FLIC) += s390_flic.o obj-$(CONFIG_S390_FLIC_KVM) += s390_flic_kvm.o obj-$(CONFIG_ASPEED_SOC) += aspeed_vic.o obj-$(CONFIG_ARM_GIC) += arm_gicv3_cpuif.o +obj-$(CONFIG_MIPS_CPS) += mips_gic.o diff --git a/hw/intc/mips_gic.c b/hw/intc/mips_gic.c new file mode 100644 index 000..6e25773 --- /dev/null +++ b/hw/intc/mips_gic.c @@ -0,0 +1,460 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. + * Authors: Sanjay Lal + * + * Copyright (C) 2016 Imagination Technologies + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "qapi/error.h" +#include "hw/hw.h" +#include "hw/sysbus.h" +#include "exec/memory.h" +#include "sysemu/sysemu.h" +#include "sysemu/kvm.h" +#include "kvm_mips.h" +#include "hw/intc/mips_gic.h" + +static void mips_gic_set_vp_irq(MIPSGICState *gic, int vp, int pin, int level) +{ +int ored_level = level; +int i; + +/* ORing pending registers sharing same pin */ +if (!ored_level) { +for (i = 0; i < gic->num_irq; i++) { +if ((gic->irq_state[i].map_pin & GIC_MAP_MSK) == pin && +gic->irq_state[i].map_vp == vp && +gic->irq_state[i].enabled) { +ored_level |= gic->irq_state[i].pending; +} +if (ored_level) { +/* no need to iterate all interrupts */ +break; +} +} +if (((gic->vps[vp].compare_map & GIC_MAP_MSK) == pin) && +(gic->vps[vp].mask & GIC_VP_MASK_CMP_MSK)) { +/* ORing with local pending register (count/compare) */ +ored_level |= (gic->vps[vp].pend & GIC_VP_MASK_CMP_MSK) >> + GIC_VP_MASK_CMP_SHF; +} +} +if (kvm_enabled()) { +kvm_mips_set_ipi_interrupt(mips_env_get_cpu(gic->vps[vp].env), + pin + GIC_CPU_PIN_OFFSET, + ored_level); +} else { +qemu_set_irq(gic->vps[vp].env->irq[pin + GIC_CPU_PIN_OFFSET], + ored_level); +} +} + +static void gic_set_irq(void *opaque, int n_IRQ, int level) +{ +MIPSGICState *gic = (MIPSGICState *) opaque; +int vp = gic->irq_state[n_IRQ].map_vp; +int pin = gic->irq_state[n_IRQ].map_pin & GIC_MAP_MSK; + +gic->irq_state[n_IRQ].pending = (uint8_t) level; +if (!gic->irq_state[n_IRQ].enabled) { +/* GIC interrupt source disabled */ +return; +} +if (vp < 0 || vp >= gic->num_vps) { +return; +} +mips_gic_set_vp_irq(gic, vp, pin, level); +} + +#define OFFSET_CHECK(c) \ +do {\ +if (!(c)) { \ +goto bad_offset;\ +} \ +} while (0) + +/* GIC Read VP Local/Other Registers */ +static uint64_t gic_read_vp(MIPSGICState *gic, uint32_t vp_index, hwaddr addr, +unsigned size) +{ +switch (addr) { +case GIC_VP_CTL_OFS: +return gic->vps[vp_index].ctl; +case GIC_VP_PEND_OFS: +mips_gictimer_get_sh_count(gic->gic_timer); +return gic->vps[vp_ind
[Qemu-devel] [PULL 04/11] target-mips: add exception base to MIPS CPU
Replace hardcoded 0xbfc0 with exception_base which is initialized with this default address so there is no functional change here. However, it is now exposed and consequently it will be possible to modify it from outside of the CPU. Signed-off-by: Leon Alrae --- target-mips/cpu.h | 2 ++ target-mips/helper.c| 6 +++--- target-mips/translate.c | 9 - 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 1037f9b..fe1c4b8 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -616,6 +616,7 @@ struct CPUMIPSState { void *irq[8]; QEMUTimer *timer; /* Internal timer */ MemoryRegion *itc_tag; /* ITC Configuration Tags */ +target_ulong exception_base; /* ExceptionBase input to the core */ }; /** @@ -807,6 +808,7 @@ int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc); #define cpu_init(cpu_model) CPU(cpu_mips_init(cpu_model)) bool cpu_supports_cps_smp(const char *cpu_model); +void cpu_set_exception_base(int vp_index, target_ulong address); /* TODO QOM'ify CPU reset and remove */ void cpu_state_reset(CPUMIPSState *s); diff --git a/target-mips/helper.c b/target-mips/helper.c index 65fbef0..1402ff0 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -640,7 +640,7 @@ void mips_cpu_do_interrupt(CPUState *cs) /* EJTAG probe trap enable is not implemented... */ if (!(env->CP0_Status & (1 << CP0St_EXL))) env->CP0_Cause &= ~(1U << CP0Ca_BD); -env->active_tc.PC = (int32_t)0xBFC00480; +env->active_tc.PC = env->exception_base + 0x480; set_hflags_for_handler(env); break; case EXCP_RESET: @@ -667,7 +667,7 @@ void mips_cpu_do_interrupt(CPUState *cs) env->hflags &= ~(MIPS_HFLAG_KSU); if (!(env->CP0_Status & (1 << CP0St_EXL))) env->CP0_Cause &= ~(1U << CP0Ca_BD); -env->active_tc.PC = (int32_t)0xBFC0; +env->active_tc.PC = env->exception_base; set_hflags_for_handler(env); break; case EXCP_EXT_INTERRUPT: @@ -849,7 +849,7 @@ void mips_cpu_do_interrupt(CPUState *cs) } env->hflags &= ~MIPS_HFLAG_BMASK; if (env->CP0_Status & (1 << CP0St_BEV)) { -env->active_tc.PC = (int32_t)0xBFC00200; +env->active_tc.PC = env->exception_base + 0x200; } else { env->active_tc.PC = (int32_t)(env->CP0_EBase & ~0x3ff); } diff --git a/target-mips/translate.c b/target-mips/translate.c index cc321e9..c302fa3 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -20169,6 +20169,7 @@ MIPSCPU *cpu_mips_init(const char *cpu_model) cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU)); env = &cpu->env; env->cpu_model = def; +env->exception_base = (int32_t)0xBFC0; #ifndef CONFIG_USER_ONLY mmu_init(env, def); @@ -20191,6 +20192,12 @@ bool cpu_supports_cps_smp(const char *cpu_model) return (def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0; } +void cpu_set_exception_base(int vp_index, target_ulong address) +{ +MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index)); +vp->env.exception_base = address; +} + void cpu_state_reset(CPUMIPSState *env) { MIPSCPU *cpu = mips_env_get_cpu(env); @@ -20281,7 +20288,7 @@ void cpu_state_reset(CPUMIPSState *env) } else { env->CP0_ErrorEPC = env->active_tc.PC; } -env->active_tc.PC = (int32_t)0xBFC0; +env->active_tc.PC = env->exception_base; env->CP0_Random = env->tlb->nb_tlb - 1; env->tlb->tlb_in_use = env->tlb->nb_tlb; env->CP0_Wired = 0; -- 2.7.4
[Qemu-devel] [PULL 10/11] target-mips: support CP0.Config4.AE bit
From: Paul Burton The read-only Config4.AE bit set denotes extended 10 bits ASID. Signed-off-by: Paul Burton Signed-off-by: James Hogan Signed-off-by: Leon Alrae --- target-mips/cpu.h | 1 + target-mips/translate.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 3e233ad..2c45839 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -468,6 +468,7 @@ struct CPUMIPSState { int32_t CP0_Config4_rw_bitmask; #define CP0C4_M31 #define CP0C4_IE 29 +#define CP0C4_AE 28 #define CP0C4_KScrExist 16 #define CP0C4_MMUExtDef 14 #define CP0C4_FTLBPageSize 8 diff --git a/target-mips/translate.c b/target-mips/translate.c index 01510b3..bab52cb 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -20302,7 +20302,8 @@ void cpu_state_reset(CPUMIPSState *env) if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) { env->CP0_CMGCRBase = 0x1fbf8000 >> 4; } -env->CP0_EntryHi_ASID_mask = 0xff; +env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ? + 0x3ff : 0xff; env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL); /* vectored interrupts not implemented, timer on int 7, no performance counters. */ -- 2.7.4
[Qemu-devel] [PULL 00/11] target-mips queue
Hi, This pull request adds MIPS CPS features needed to boot MIPSr6 SMP Linux on multiple VPs, renames MIPS64R6-generic to I6400 and adds 10-bit ASID support. Thanks, Leon Cc: Peter Maydell Cc: Aurelien Jarno The following changes since commit e2c8f9e44e07d8210049abaa6042ec3c956f1dd4: Merge remote-tracking branch 'remotes/thibault/tags/samuel-thibault' into staging (2016-07-04 10:49:17 +0100) are available in the git repository at: git://github.com/lalrae/qemu.git tags/mips-20160712 for you to fetch changes up to cdc46fab07a122dfcc8a1054510a68d936ae3440: target-mips: enable 10-bit ASIDs in I6400 CPU (2016-07-12 09:10:21 +0100) MIPS patches 2016-07-12 Changes: * support 10-bit ASIDs * MIPS64R6-generic renamed to I6400 * initial GIC support * implement RESET_BASE register in CM GCR ---- Leon Alrae (6): hw/mips/cps: create GIC block inside CPS target-mips: add exception base to MIPS CPU hw/mips_cpc: make VP correctly start from the reset vector hw/mips_cmgcr: implement RESET_BASE register in CM GCR target-mips: replace MIPS64R6-generic with the real I6400 CPU model target-mips: enable 10-bit ASIDs in I6400 CPU Paul Burton (3): target-mips: add ASID mask field and replace magic values target-mips: change ASID type to hold more than 8 bits target-mips: support CP0.Config4.AE bit Yongbok Kim (2): hw/mips: implement GIC Interval Timer hw/mips: implement Global Interrupt Controller hw/intc/Makefile.objs| 1 + hw/intc/mips_gic.c | 460 +++ hw/mips/cps.c| 25 ++- hw/mips/mips_malta.c | 4 +- hw/misc/mips_cmgcr.c | 87 +++- hw/misc/mips_cpc.c | 5 +- hw/timer/Makefile.objs | 1 + hw/timer/mips_gictimer.c | 142 include/hw/intc/mips_gic.h | 216 ++ include/hw/mips/cps.h| 2 + include/hw/misc/mips_cmgcr.h | 27 +++ include/hw/timer/mips_gictimer.h | 46 target-mips/cpu.h| 7 +- target-mips/helper.c | 16 +- target-mips/machine.c| 10 +- target-mips/op_helper.c | 33 +-- target-mips/translate.c | 11 +- target-mips/translate_init.c | 22 +- 18 files changed, 1059 insertions(+), 56 deletions(-) create mode 100644 hw/intc/mips_gic.c create mode 100644 hw/timer/mips_gictimer.c create mode 100644 include/hw/intc/mips_gic.h create mode 100644 include/hw/timer/mips_gictimer.h
[Qemu-devel] [PULL 03/11] hw/mips/cps: create GIC block inside CPS
Add GIC to CPS and expose its interrupt pins instead of CPU's. Signed-off-by: Leon Alrae --- hw/mips/cps.c| 25 ++--- hw/mips/mips_malta.c | 4 +--- hw/misc/mips_cmgcr.c | 33 + include/hw/mips/cps.h| 2 ++ include/hw/misc/mips_cmgcr.h | 9 + 5 files changed, 63 insertions(+), 10 deletions(-) diff --git a/hw/mips/cps.c b/hw/mips/cps.c index 61208f8..77c6217 100644 --- a/hw/mips/cps.c +++ b/hw/mips/cps.c @@ -26,13 +26,8 @@ qemu_irq get_cps_irq(MIPSCPSState *s, int pin_number) { -MIPSCPU *cpu = MIPS_CPU(first_cpu); -CPUMIPSState *env = &cpu->env; - assert(pin_number < s->num_irq); - -/* TODO: return GIC pins once implemented */ -return env->irq[pin_number]; +return s->gic.irq_state[pin_number].irq; } static void mips_cps_init(Object *obj) @@ -130,6 +125,21 @@ static void mips_cps_realize(DeviceState *dev, Error **errp) memory_region_add_subregion(&s->container, 0, sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpc), 0)); +/* Global Interrupt Controller */ +object_initialize(&s->gic, sizeof(s->gic), TYPE_MIPS_GIC); +qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default()); + +object_property_set_int(OBJECT(&s->gic), s->num_vp, "num-vp", &err); +object_property_set_int(OBJECT(&s->gic), 128, "num-irq", &err); +object_property_set_bool(OBJECT(&s->gic), true, "realized", &err); +if (err != NULL) { +error_propagate(errp, err); +return; +} + +memory_region_add_subregion(&s->container, 0, +sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gic), 0)); + /* Global Configuration Registers */ gcr_base = env->CP0_CMGCRBase << 4; @@ -139,6 +149,7 @@ static void mips_cps_realize(DeviceState *dev, Error **errp) object_property_set_int(OBJECT(&s->gcr), s->num_vp, "num-vp", &err); object_property_set_int(OBJECT(&s->gcr), 0x800, "gcr-rev", &err); object_property_set_int(OBJECT(&s->gcr), gcr_base, "gcr-base", &err); +object_property_set_link(OBJECT(&s->gcr), OBJECT(&s->gic.mr), "gic", &err); object_property_set_link(OBJECT(&s->gcr), OBJECT(&s->cpc.mr), "cpc", &err); object_property_set_bool(OBJECT(&s->gcr), true, "realized", &err); if (err != NULL) { @@ -152,7 +163,7 @@ static void mips_cps_realize(DeviceState *dev, Error **errp) static Property mips_cps_properties[] = { DEFINE_PROP_UINT32("num-vp", MIPSCPSState, num_vp, 1), -DEFINE_PROP_UINT32("num-irq", MIPSCPSState, num_irq, 8), +DEFINE_PROP_UINT32("num-irq", MIPSCPSState, num_irq, 256), DEFINE_PROP_STRING("cpu-model", MIPSCPSState, cpu_model), DEFINE_PROP_END_OF_LIST() }; diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index 5c8ba44..34d41ef 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -955,9 +955,7 @@ static void create_cps(MaltaState *s, const char *cpu_model, sysbus_mmio_map_overlap(SYS_BUS_DEVICE(s->cps), 0, 0, 1); -/* FIXME: When GIC is present then we should use GIC's IRQ 3. - Until then CPS exposes CPU's IRQs thus use the default IRQ 2. */ -*i8259_irq = get_cps_irq(s->cps, 2); +*i8259_irq = get_cps_irq(s->cps, 3); *cbus_irq = NULL; } diff --git a/hw/misc/mips_cmgcr.c b/hw/misc/mips_cmgcr.c index 40f3464..e6cf17d 100644 --- a/hw/misc/mips_cmgcr.c +++ b/hw/misc/mips_cmgcr.c @@ -17,12 +17,18 @@ #include "sysemu/sysemu.h" #include "hw/misc/mips_cmgcr.h" #include "hw/misc/mips_cpc.h" +#include "hw/intc/mips_gic.h" static inline bool is_cpc_connected(MIPSGCRState *s) { return s->cpc_mr != NULL; } +static inline bool is_gic_connected(MIPSGCRState *s) +{ +return s->gic_mr != NULL; +} + static inline void update_cpc_base(MIPSGCRState *gcr, uint64_t val) { if (is_cpc_connected(gcr)) { @@ -36,6 +42,19 @@ static inline void update_cpc_base(MIPSGCRState *gcr, uint64_t val) } } +static inline void update_gic_base(MIPSGCRState *gcr, uint64_t val) +{ +if (is_gic_connected(gcr)) { +gcr->gic_base = val & GCR_GIC_BASE_MSK; +memory_region_transaction_begin(); +memory_region_set_address(gcr->gic_mr, + gcr->gic_base & GCR_GIC_BASE_GICBASE_MSK); +memory_region_set_enabled(gcr->gic_mr, + gcr->gic_base & GCR_GIC_BASE_GICEN_MSK); +memory_region_transaction_commit(); +} +} + /* Read GCR registers */ static uint64_t gcr_read(void *opaque, hwaddr addr, un
[Qemu-devel] [PULL 07/11] target-mips: replace MIPS64R6-generic with the real I6400 CPU model
MIPS64R6-generic gradually gets closer to I6400 CPU, feature-wise. Rename it to make it clear which MIPS processor it is supposed to emulate. Signed-off-by: Leon Alrae --- target-mips/translate_init.c | 20 +--- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c index b10284c..c43bdb7 100644 --- a/target-mips/translate_init.c +++ b/target-mips/translate_init.c @@ -671,26 +671,23 @@ static const mips_def_t mips_defs[] = .mmu_type = MMU_TYPE_R4000, }, { -/* A generic CPU supporting MIPS64 Release 6 ISA. - FIXME: Support IEEE 754-2008 FP. - Eventually this should be replaced by a real CPU model. */ -.name = "MIPS64R6-generic", -.CP0_PRid = 0x0001, +.name = "I6400", +.CP0_PRid = 0x1A900, .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AR) | (0x2 << CP0C0_AT) | (MMU_TYPE_R4000 << CP0C0_MT), -.CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (63 << CP0C1_MMU) | - (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) | - (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) | +.CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (15 << CP0C1_MMU) | + (2 << CP0C1_IS) | (5 << CP0C1_IL) | (3 << CP0C1_IA) | + (2 << CP0C1_DS) | (5 << CP0C1_DL) | (3 << CP0C1_DA) | (0 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), .CP0_Config2 = MIPS_CONFIG2, .CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | (1 << CP0C3_CMGCR) | (1 << CP0C3_MSAP) | (1 << CP0C3_BP) | (1 << CP0C3_BI) | (1 << CP0C3_ULRI) | - (1 << CP0C3_RXI) | (1 << CP0C3_LPA), + (1 << CP0C3_RXI) | (1 << CP0C3_LPA) | (1 << CP0C3_VInt), .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) | (3 << CP0C4_IE) | (0xfc << CP0C4_KScrExist), .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_XNP) | (1 << CP0C5_VP) | - (1 << CP0C5_LLB), + (1 << CP0C5_LLB) | (1 << CP0C5_MRP), .CP0_Config5_rw_bitmask = (1 << CP0C5_MSAEn) | (1 << CP0C5_SBRI) | (1 << CP0C5_FRE) | (1 << CP0C5_UFE), .CP0_LLAddr_rw_bitmask = 0, @@ -703,9 +700,10 @@ static const mips_def_t mips_defs[] = .CP0_PageGrain_rw_bitmask = (1 << CP0PG_ELPA), .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_HAS2008) | (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) | -(1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV), +(1 << FCR0_S) | (0x03 << FCR0_PRID) | (0x0 << FCR0_REV), .CP1_fcr31 = (1 << FCR31_ABS2008) | (1 << FCR31_NAN2008), .CP1_fcr31_rw_bitmask = 0x0103, +.MSAIR = 0x03 << MSAIR_ProcID, .SEGBITS = 48, .PABITS = 48, .insn_flags = CPU_MIPS64R6 | ASE_MSA, -- 2.7.4
[Qemu-devel] [PULL 05/11] hw/mips_cpc: make VP correctly start from the reset vector
When VP enters the Run state it starts execution from the reset vector. Currently used CPU_INTERRUPT_WAKE does not do that if reset exception base has been modified. Therefore fix that by simply resetting given VP. Drop the usage of CPU_INTERRUPT_WAKE also in VP_STOP and instead raise the CPU_INTERRUPT_HALT to halt a VP. Signed-off-by: Leon Alrae --- hw/misc/mips_cpc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hw/misc/mips_cpc.c b/hw/misc/mips_cpc.c index e6a35dd..6d34574 100644 --- a/hw/misc/mips_cpc.c +++ b/hw/misc/mips_cpc.c @@ -37,7 +37,7 @@ static void cpc_run_vp(MIPSCPCState *cpc, uint64_t vp_run) CPU_FOREACH(cs) { uint64_t i = 1ULL << cs->cpu_index; if (i & vp_run & ~cpc->vp_running) { -cpu_interrupt(cs, CPU_INTERRUPT_WAKE); +cpu_reset(cs); cpc->vp_running |= i; } } @@ -50,8 +50,7 @@ static void cpc_stop_vp(MIPSCPCState *cpc, uint64_t vp_stop) CPU_FOREACH(cs) { uint64_t i = 1ULL << cs->cpu_index; if (i & vp_stop & cpc->vp_running) { -cs->halted = 1; -cpu_reset_interrupt(cs, CPU_INTERRUPT_WAKE); +cpu_interrupt(cs, CPU_INTERRUPT_HALT); cpc->vp_running &= ~i; } } -- 2.7.4
Re: [Qemu-devel] [PULL 03/36] hw/pci: delay bus_master_enable_region initialization
Hi, This commit causes regressions in my MIPS tests. QEMU segfaults when booting Linux on Malta board; this can be easily reproduced with Aurelien's Debian images: wget https://people.debian.org/~aurel32/qemu/mipsel/vmlinux-3.2.0-4-5kc-malta wget https://people.debian.org/~aurel32/qemu/mipsel/debian_wheezy_mipsel_standard.qcow2 qemu-system-mips64el -M malta -kernel vmlinux-3.2.0-4-5kc-malta -hda debian_wheezy_mipsel_standard.qcow2 -append "root=/dev/sda1 console=ttyS0" -nographic ... [1.468000] ata2.00: ATAPI: QEMU DVD-ROM, 2.5+, max UDMA/100 [1.476000] ata1.00: ATA-7: QEMU HARDDISK, 2.5+, max UDMA/100 [1.476000] ata1.00: 52428800 sectors, multi 16: LBA48 [1.48] ata2.00: configured for UDMA/33 [1.484000] ata1.00: configured for UDMA/33 [1.536000] scsi 0:0:0:0: Direct-Access ATA QEMU HARDDISK2.5+ PQ: 0 ANSI: 5 [1.552000] sd 0:0:0:0: [sda] 52428800 512-byte logical blocks: (26.8 GB/25.0 GiB) [1.568000] scsi 1:0:0:0: CD-ROMQEMU QEMU DVD-ROM 2.5+ PQ: 0 ANSI: 5 [1.576000] sd 0:0:0:0: [sda] Write Protect is off [1.58] sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 0x7fffec79e700 (LWP 29679)] 0x7792f806 in address_space_lookup_region (d=0x0, addr=12582912, resolve_subpage=true) at /user/lea/dev/qemu/exec.c:359 359 MemoryRegionSection *section = atomic_read(&d->mru_section); (gdb) bt #0 0x7792f806 in address_space_lookup_region (d=0x0, addr=12582912, resolve_subpage=true) at /user/lea/dev/qemu/exec.c:359 #1 0x7792f95e in address_space_translate_internal (d=0x0, addr=12582912, xlat=0x7fffec79ca30, plen=0x7fffec79cb18, resolve_subpage=true) at /user/lea/dev/qemu/exec.c:390 #2 0x7792fb5a in address_space_translate (as=0x78bc1ef0, addr=12582912, xlat=0x7fffec79cb10, plen=0x7fffec79cb18, is_write=false) at /user/lea/dev/qemu/exec.c:428 #3 0x77935720 in address_space_read_full (as=0x78bc1ef0, addr=12582912, attrs=..., buf=0x7fffec79cd60 "\260^\324\370", , len=8) at /user/lea/dev/qemu/exec.c:2724 #4 0x77935821 in address_space_read (as=0x78bc1ef0, addr=12582912, attrs=..., buf=0x7fffec79cd60 "\260^\324\370", , len=8, is_write=false) at /user/lea/dev/qemu/include/exec/memory.h:1476 #5 address_space_rw (as=0x78bc1ef0, addr=12582912, attrs=..., buf=0x7fffec79cd60 "\260^\324\370", , len=8, is_write=false) at /user/lea/dev/qemu/exec.c:2739 #6 0x77baf9a7 in dma_memory_rw_relaxed (as=0x78bc1ef0, addr=12582912, buf=0x7fffec79cd60, len=8, dir=DMA_DIRECTION_TO_DEVICE) at /user/lea/dev/qemu/include/sysemu/dma.h:87 #7 0x77bafa28 in dma_memory_rw (as=0x78bc1ef0, addr=12582912, buf=0x7fffec79cd60, len=8, dir=DMA_DIRECTION_TO_DEVICE) at /user/lea/dev/qemu/include/sysemu/dma.h:110 #8 0x77bafad3 in pci_dma_rw (dev=0x78bc1ce0, addr=12582912, buf=0x7fffec79cd60, len=8, dir=DMA_DIRECTION_TO_DEVICE) at /user/lea/dev/qemu/include/hw/pci/pci.h:731 #9 0x77bafb3c in pci_dma_read (dev=0x78bc1ce0, addr=12582912, buf=0x7fffec79cd60, len=8) at /user/lea/dev/qemu/include/hw/pci/pci.h:738 #10 0x77baff6d in bmdma_prepare_buf (dma=0x78bc3620, limit=4096) at /user/lea/dev/qemu/hw/ide/pci.c:85 #11 0x77ba66bc in ide_dma_cb (opaque=0x78bc25e8, ret=0) at /user/lea/dev/qemu/hw/ide/core.c:844 #12 0x77bb0615 in bmdma_cmd_writeb (bm=0x78bc3620, val=9) at /user/lea/dev/qemu/hw/ide/pci.c:245 #13 0x77bb1408 in bmdma_write (opaque=0x78bc3620, addr=0, val=9, size=1) at /user/lea/dev/qemu/hw/ide/piix.c:77 #14 0x77988548 in memory_region_write_accessor (mr=0x78bc3778, addr=0, value=0x7fffec79cfd8, size=1, shift=0, mask=255, attrs=...) at /user/lea/dev/qemu/memory.c:525 #15 0x779887dd in access_with_adjusted_size (addr=0, value=0x7fffec79cfd8, size=1, access_size_min=1, access_size_max=4, access=0x7798843e , mr=0x78bc3778, attrs=...) at /user/lea/dev/qemu/memory.c:591 #16 0x7798bc6e in memory_region_dispatch_write (mr=0x78bc3778, addr=0, data=9, size=1, attrs=...) at /user/lea/dev/qemu/memory.c:1262 #17 0x77935294 in address_space_write_continue (as=0x78921a90, addr=402657344, attrs=..., buf=0x7fffec79d170 "\t\345y\354\377\177", len=1, addr1=0, l=1, mr=0x78bc3778) at /user/lea/dev/qemu/exec.c:2590 #18 0x7793540d in address_space_write (as=0x78921a90, addr=402657344, attrs=..., buf=0x7fffec79d170 "\t\345y\354\377\177", len=1) at /user/lea/dev/qemu/exec.c:2635 #19 0x779344c0 in subpage_write (opaque=0x7fffd4569730, addr=64, value=9, len=1, attrs=...) at /user/lea/dev/qemu/exec.c:2221 #20 0x77988678 in memory_region_write_with_attrs_accessor (mr=0x7fffd4569730, addr=64, value=0x7fffec79d2b8, size=1, shift=0, mask=255, attrs=...) at /user/lea/dev/qemu/memory.c:551 #21 0x7
[Qemu-devel] [PATCH 4/4] target-mips: enable 10-bit ASIDs in I6400 CPU
Signed-off-by: Leon Alrae --- target-mips/translate_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c index c43bdb7..39ed5c4 100644 --- a/target-mips/translate_init.c +++ b/target-mips/translate_init.c @@ -685,7 +685,7 @@ static const mips_def_t mips_defs[] = (1 << CP0C3_BP) | (1 << CP0C3_BI) | (1 << CP0C3_ULRI) | (1 << CP0C3_RXI) | (1 << CP0C3_LPA) | (1 << CP0C3_VInt), .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) | (3 << CP0C4_IE) | - (0xfc << CP0C4_KScrExist), + (1 << CP0C4_AE) | (0xfc << CP0C4_KScrExist), .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_XNP) | (1 << CP0C5_VP) | (1 << CP0C5_LLB) | (1 << CP0C5_MRP), .CP0_Config5_rw_bitmask = (1 << CP0C5_MSAEn) | (1 << CP0C5_SBRI) | -- 2.7.4
[Qemu-devel] [PATCH 1/4] target-mips: add ASID mask field and replace magic values
From: Paul Burton Signed-off-by: Paul Burton Signed-off-by: James Hogan Signed-off-by: Leon Alrae --- target-mips/cpu.h | 2 ++ target-mips/helper.c| 10 +- target-mips/op_helper.c | 27 +++ target-mips/translate.c | 1 + 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/target-mips/cpu.h b/target-mips/cpu.h index c2e3586..72053b3 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -343,6 +343,7 @@ struct CPUMIPSState { int32_t CP0_Count; target_ulong CP0_EntryHi; #define CP0EnHi_EHINV 10 +target_ulong CP0_EntryHi_ASID_mask; int32_t CP0_Compare; int32_t CP0_Status; #define CP0St_CU3 31 @@ -503,6 +504,7 @@ struct CPUMIPSState { int CP0_LLAddr_shift; target_ulong CP0_WatchLo[8]; int32_t CP0_WatchHi[8]; +#define CP0WH_ASID 16 target_ulong CP0_XContext; int32_t CP0_Framemask; int32_t CP0_Debug; diff --git a/target-mips/helper.c b/target-mips/helper.c index 1402ff0..1e194e9 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -67,7 +67,7 @@ int fixed_mmu_map_address (CPUMIPSState *env, hwaddr *physical, int *prot, int r4k_map_address (CPUMIPSState *env, hwaddr *physical, int *prot, target_ulong address, int rw, int access_type) { -uint8_t ASID = env->CP0_EntryHi & 0xFF; +uint8_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; int i; for (i = 0; i < env->tlb->tlb_in_use; i++) { @@ -249,7 +249,7 @@ void sync_c0_status(CPUMIPSState *env, CPUMIPSState *cpu, int tc) cu = (v >> CP0St_CU0) & 0xf; mx = (v >> CP0St_MX) & 0x1; ksu = (v >> CP0St_KSU) & 0x3; -asid = env->CP0_EntryHi & 0xff; +asid = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; tcstatus = cu << CP0TCSt_TCU0; tcstatus |= mx << CP0TCSt_TMX; @@ -395,8 +395,8 @@ static void raise_mmu_exception(CPUMIPSState *env, target_ulong address, env->CP0_BadVAddr = address; env->CP0_Context = (env->CP0_Context & ~0x007f) | ((address >> 9) & 0x0070); -env->CP0_EntryHi = -(env->CP0_EntryHi & 0xFF) | (address & (TARGET_PAGE_MASK << 1)); +env->CP0_EntryHi = (env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask) | + (address & (TARGET_PAGE_MASK << 1)); #if defined(TARGET_MIPS64) env->CP0_EntryHi &= env->SEGMask; env->CP0_XContext = @@ -898,7 +898,7 @@ void r4k_invalidate_tlb (CPUMIPSState *env, int idx, int use_extra) r4k_tlb_t *tlb; target_ulong addr; target_ulong end; -uint8_t ASID = env->CP0_EntryHi & 0xFF; +uint8_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; target_ulong mask; tlb = &env->tlb->mmu.r4k.tlb[idx]; diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 69daade..1562f22 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -679,7 +679,7 @@ static void sync_c0_tcstatus(CPUMIPSState *cpu, int tc, tcu = (v >> CP0TCSt_TCU0) & 0xf; tmx = (v >> CP0TCSt_TMX) & 0x1; -tasid = v & 0xff; +tasid = v & cpu->CP0_EntryHi_ASID_mask; tksu = (v >> CP0TCSt_TKSU) & 0x3; status = tcu << CP0St_CU0; @@ -690,7 +690,7 @@ static void sync_c0_tcstatus(CPUMIPSState *cpu, int tc, cpu->CP0_Status |= status; /* Sync the TASID with EntryHi. */ -cpu->CP0_EntryHi &= ~0xff; +cpu->CP0_EntryHi &= ~cpu->CP0_EntryHi_ASID_mask; cpu->CP0_EntryHi |= tasid; compute_hflags(cpu); @@ -702,7 +702,7 @@ static void sync_c0_entryhi(CPUMIPSState *cpu, int tc) int32_t *tcst; uint32_t asid, v = cpu->CP0_EntryHi; -asid = v & 0xff; +asid = v & cpu->CP0_EntryHi_ASID_mask; if (tc == cpu->current_tc) { tcst = &cpu->active_tc.CP0_TCStatus; @@ -710,7 +710,7 @@ static void sync_c0_entryhi(CPUMIPSState *cpu, int tc) tcst = &cpu->tcs[tc].CP0_TCStatus; } -*tcst &= ~0xff; +*tcst &= ~cpu->CP0_EntryHi_ASID_mask; *tcst |= asid; } @@ -1403,7 +1403,7 @@ void helper_mtc0_count(CPUMIPSState *env, target_ulong arg1) void helper_mtc0_entryhi(CPUMIPSState *env, target_ulong arg1) { target_ulong old, val, mask; -mask = (TARGET_PAGE_MASK << 1) | 0xFF; +mask = (TARGET_PAGE_MASK << 1) | env->CP0_EntryHi_ASID_mask; if (((env->CP0_Config4 >> CP0C4_IE) & 0x3) >= 2) { mask |= 1 << CP0EnHi_EHINV; } @@ -1429,8 +1429,10 @@ void helper_mtc0_entryhi(CPUMIPSState *env, target_ulong arg1) sync_c0_entryhi(env, env->current_tc); } /* If the ASID changes, flush qemu's TLB. */ -if ((old & 0xFF) != (val & 0xFF)) +if ((old &a
[Qemu-devel] [PATCH 2/4] target-mips: change ASID type to hold more than 8 bits
From: Paul Burton ASID currently has uint8_t type which is too small since some processors support more than 8 bits ASID. Therefore change its type to uint16_t. Signed-off-by: Paul Burton Signed-off-by: James Hogan Signed-off-by: Leon Alrae --- target-mips/cpu.h | 2 +- target-mips/helper.c| 4 ++-- target-mips/machine.c | 10 +- target-mips/op_helper.c | 8 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 72053b3..62a149e 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -19,7 +19,7 @@ typedef struct r4k_tlb_t r4k_tlb_t; struct r4k_tlb_t { target_ulong VPN; uint32_t PageMask; -uint8_t ASID; +uint16_t ASID; unsigned int G:1; unsigned int C0:3; unsigned int C1:3; diff --git a/target-mips/helper.c b/target-mips/helper.c index 1e194e9..9fbca26 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -67,7 +67,7 @@ int fixed_mmu_map_address (CPUMIPSState *env, hwaddr *physical, int *prot, int r4k_map_address (CPUMIPSState *env, hwaddr *physical, int *prot, target_ulong address, int rw, int access_type) { -uint8_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; +uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; int i; for (i = 0; i < env->tlb->tlb_in_use; i++) { @@ -898,7 +898,7 @@ void r4k_invalidate_tlb (CPUMIPSState *env, int idx, int use_extra) r4k_tlb_t *tlb; target_ulong addr; target_ulong end; -uint8_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; +uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; target_ulong mask; tlb = &env->tlb->mmu.r4k.tlb[idx]; diff --git a/target-mips/machine.c b/target-mips/machine.c index 7314cfe..a27f2f1 100644 --- a/target-mips/machine.c +++ b/target-mips/machine.c @@ -132,7 +132,7 @@ static int get_tlb(QEMUFile *f, void *pv, size_t size) qemu_get_betls(f, &v->VPN); qemu_get_be32s(f, &v->PageMask); -qemu_get_8s(f, &v->ASID); +qemu_get_be16s(f, &v->ASID); qemu_get_be16s(f, &flags); v->G = (flags >> 10) & 1; v->C0 = (flags >> 7) & 3; @@ -156,7 +156,7 @@ static void put_tlb(QEMUFile *f, void *pv, size_t size) { r4k_tlb_t *v = pv; -uint8_t asid = v->ASID; +uint16_t asid = v->ASID; uint16_t flags = ((v->EHINV << 15) | (v->RI1 << 14) | (v->RI0 << 13) | @@ -172,7 +172,7 @@ static void put_tlb(QEMUFile *f, void *pv, size_t size) qemu_put_betls(f, &v->VPN); qemu_put_be32s(f, &v->PageMask); -qemu_put_8s(f, &asid); +qemu_put_be16s(f, &asid); qemu_put_be16s(f, &flags); qemu_put_be64s(f, &v->PFN[0]); qemu_put_be64s(f, &v->PFN[1]); @@ -192,8 +192,8 @@ const VMStateInfo vmstate_info_tlb = { const VMStateDescription vmstate_tlb = { .name = "cpu/tlb", -.version_id = 1, -.minimum_version_id = 1, +.version_id = 2, +.minimum_version_id = 2, .fields = (VMStateField[]) { VMSTATE_UINT32(nb_tlb, CPUMIPSTLBContext), VMSTATE_UINT32(tlb_in_use, CPUMIPSTLBContext), diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 1562f22..31c85f9 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -2013,7 +2013,7 @@ void r4k_helper_tlbinv(CPUMIPSState *env) { int idx; r4k_tlb_t *tlb; -uint8_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; +uint16_t ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; for (idx = 0; idx < env->tlb->nb_tlb; idx++) { tlb = &env->tlb->mmu.r4k.tlb[idx]; @@ -2039,7 +2039,7 @@ void r4k_helper_tlbwi(CPUMIPSState *env) r4k_tlb_t *tlb; int idx; target_ulong VPN; -uint8_t ASID; +uint16_t ASID; bool G, V0, D0, V1, D1; idx = (env->CP0_Index & ~0x8000) % env->tlb->nb_tlb; @@ -2081,7 +2081,7 @@ void r4k_helper_tlbp(CPUMIPSState *env) target_ulong mask; target_ulong tag; target_ulong VPN; -uint8_t ASID; +uint16_t ASID; int i; ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; @@ -2136,7 +2136,7 @@ static inline uint64_t get_entrylo_pfn_from_tlb(uint64_t tlb_pfn) void r4k_helper_tlbr(CPUMIPSState *env) { r4k_tlb_t *tlb; -uint8_t ASID; +uint16_t ASID; int idx; ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask; -- 2.7.4
[Qemu-devel] [PATCH 0/4] target-mips: add extended ASID support
Currently we assume 8-bit ASID everywhere in target-mips code, whereas MIPS architecture allows greater ASIDs. If CP0.Config4.AE bit is set then EntryHi.ASID is extended to 10 bits. This feature is present in real I6400 CPU therefore implement and enable it in emulated by QEMU I6400 model. This series is based on the patch adding I6400 CPU: https://lists.gnu.org/archive/html/qemu-devel/2016-06/msg07604.html Thanks, Leon Leon Alrae (1): target-mips: enable 10-bit ASIDs in I6400 CPU Paul Burton (3): target-mips: add ASID mask field and replace magic values target-mips: change ASID type to hold more than 8 bits target-mips: support CP0.Config4.AE bit target-mips/cpu.h| 5 - target-mips/helper.c | 10 +- target-mips/machine.c| 10 +- target-mips/op_helper.c | 33 ++--- target-mips/translate.c | 2 ++ target-mips/translate_init.c | 2 +- 6 files changed, 35 insertions(+), 27 deletions(-) -- 2.7.4
[Qemu-devel] [PATCH 3/4] target-mips: support CP0.Config4.AE bit
From: Paul Burton The read-only Config4.AE bit set denotes extended 10 bits ASID. Signed-off-by: Paul Burton Signed-off-by: James Hogan Signed-off-by: Leon Alrae --- target-mips/cpu.h | 1 + target-mips/translate.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 62a149e..3a4720d 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -468,6 +468,7 @@ struct CPUMIPSState { int32_t CP0_Config4_rw_bitmask; #define CP0C4_M31 #define CP0C4_IE 29 +#define CP0C4_AE 28 #define CP0C4_KScrExist 16 #define CP0C4_MMUExtDef 14 #define CP0C4_FTLBPageSize 8 diff --git a/target-mips/translate.c b/target-mips/translate.c index 01510b3..bab52cb 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -20302,7 +20302,8 @@ void cpu_state_reset(CPUMIPSState *env) if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) { env->CP0_CMGCRBase = 0x1fbf8000 >> 4; } -env->CP0_EntryHi_ASID_mask = 0xff; +env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ? + 0x3ff : 0xff; env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL); /* vectored interrupts not implemented, timer on int 7, no performance counters. */ -- 2.7.4
[Qemu-devel] [PATCH] target-mips: replace MIPS64R6-generic with the real I6400 CPU model
MIPS64R6-generic gradually gets closer to I6400 CPU, feature-wise. Rename it to make it clear which MIPS processor it is supposed to emulate. Signed-off-by: Leon Alrae --- target-mips/translate_init.c | 20 +--- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c index b10284c..c43bdb7 100644 --- a/target-mips/translate_init.c +++ b/target-mips/translate_init.c @@ -671,26 +671,23 @@ static const mips_def_t mips_defs[] = .mmu_type = MMU_TYPE_R4000, }, { -/* A generic CPU supporting MIPS64 Release 6 ISA. - FIXME: Support IEEE 754-2008 FP. - Eventually this should be replaced by a real CPU model. */ -.name = "MIPS64R6-generic", -.CP0_PRid = 0x0001, +.name = "I6400", +.CP0_PRid = 0x1A900, .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AR) | (0x2 << CP0C0_AT) | (MMU_TYPE_R4000 << CP0C0_MT), -.CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (63 << CP0C1_MMU) | - (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) | - (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) | +.CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (15 << CP0C1_MMU) | + (2 << CP0C1_IS) | (5 << CP0C1_IL) | (3 << CP0C1_IA) | + (2 << CP0C1_DS) | (5 << CP0C1_DL) | (3 << CP0C1_DA) | (0 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), .CP0_Config2 = MIPS_CONFIG2, .CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | (1 << CP0C3_CMGCR) | (1 << CP0C3_MSAP) | (1 << CP0C3_BP) | (1 << CP0C3_BI) | (1 << CP0C3_ULRI) | - (1 << CP0C3_RXI) | (1 << CP0C3_LPA), + (1 << CP0C3_RXI) | (1 << CP0C3_LPA) | (1 << CP0C3_VInt), .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) | (3 << CP0C4_IE) | (0xfc << CP0C4_KScrExist), .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_XNP) | (1 << CP0C5_VP) | - (1 << CP0C5_LLB), + (1 << CP0C5_LLB) | (1 << CP0C5_MRP), .CP0_Config5_rw_bitmask = (1 << CP0C5_MSAEn) | (1 << CP0C5_SBRI) | (1 << CP0C5_FRE) | (1 << CP0C5_UFE), .CP0_LLAddr_rw_bitmask = 0, @@ -703,9 +700,10 @@ static const mips_def_t mips_defs[] = .CP0_PageGrain_rw_bitmask = (1 << CP0PG_ELPA), .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_HAS2008) | (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) | -(1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV), +(1 << FCR0_S) | (0x03 << FCR0_PRID) | (0x0 << FCR0_REV), .CP1_fcr31 = (1 << FCR31_ABS2008) | (1 << FCR31_NAN2008), .CP1_fcr31_rw_bitmask = 0x0103, +.MSAIR = 0x03 << MSAIR_ProcID, .SEGBITS = 48, .PABITS = 48, .insn_flags = CPU_MIPS64R6 | ASE_MSA, -- 2.7.4
[Qemu-devel] [PULL 01/10] softfloat: Implement run-time-configurable meaning of signaling NaN bit
From: Aleksandar Markovic This patch modifies SoftFloat library so that it can be configured in run-time in relation to the meaning of signaling NaN bit, while, at the same time, strictly preserving its behavior on all existing platforms. Background: In floating-point calculations, there is a need for denoting undefined or unrepresentable values. This is achieved by defining certain floating-point numerical values to be NaNs (which stands for "not a number"). For additional reasons, virtually all modern floating-point unit implementations use two kinds of NaNs: quiet and signaling. The binary representations of these two kinds of NaNs, as a rule, differ only in one bit (that bit is, traditionally, the first bit of mantissa). Up to 2008, standards for floating-point did not specify all details about binary representation of NaNs. More specifically, the meaning of the bit that is used for distinguishing between signaling and quiet NaNs was not strictly prescribed. (IEEE 754-2008 was the first floating-point standard that defined that meaning clearly, see [1], p. 35) As a result, different platforms took different approaches, and that presented considerable challenge for multi-platform emulators like QEMU. Mips platform represents the most complex case among QEMU-supported platforms regarding signaling NaN bit. Up to the Release 6 of Mips architecture, "1" in signaling NaN bit denoted signaling NaN, which is opposite to IEEE 754-2008 standard. From Release 6 on, Mips architecture adopted IEEE standard prescription, and "0" denotes signaling NaN. On top of that, Mips architecture for SIMD (also known as MSA, or vector instructions) also specifies signaling bit in accordance to IEEE standard. MSA unit can be implemented with both pre-Release 6 and Release 6 main processor units. QEMU uses SoftFloat library to implement various floating-point-related instructions on all platforms. The current QEMU implementation allows for defining meaning of signaling NaN bit during build time, and is implemented via preprocessor macro called SNAN_BIT_IS_ONE. On the other hand, the change in this patch enables SoftFloat library to be configured in run-time. This configuration is meant to occur during CPU initialization, at the moment when it is definitely known what desired behavior for particular CPU (or any additional FPUs) is. The change is implemented so that it is consistent with existing implementation of similar cases. This means that structure float_status is used for passing the information about desired signaling NaN bit on each invocation of SoftFloat functions. The additional field in float_status is called snan_bit_is_one, which supersedes macro SNAN_BIT_IS_ONE. IMPORTANT: This change is not meant to create any change in emulator behavior or functionality on any platform. It just provides the means for SoftFloat library to be used in a more flexible way - in other words, it will just prepare SoftFloat library for usage related to Mips platform and its specifics regarding signaling bit meaning, which is done in some of subsequent patches from this series. Further break down of changes: 1) Added field snan_bit_is_one to the structure float_status, and correspondent setter function set_snan_bit_is_one(). 2) Constants _default_nan (used both internally and externally) converted to functions _default_nan(float_status*). This is necessary since they are dependent on signaling bit meaning. At the same time, for the sake of code cleanup and simplicity, constants _default_nan_ (used only internally within SoftFloat library) are removed, as not needed. 3) Added a float_status* argument to SoftFloat library functions XXX_is_quiet_nan(XXX a_), XXX_is_signaling_nan(XXX a_), XXX_maybe_silence_nan(XXX a_). This argument must be present in order to enable correct invocation of new version of functions XXX_default_nan(). (XXX is here) 4) Updated code for all platforms to reflect changes in SoftFloat library. This change is twofolds: it includes modifications of SoftFloat library functions invocations, and an addition of invocation of function set_snan_bit_is_one() during CPU initialization, with arguments that are appropriate for each particular platform. It was established that all platforms zero their main CPU data structures, so snan_bit_is_one(0) in appropriate places is not added, as it is not needed. [1] "IEEE Standard for Floating-Point Arithmetic", IEEE Computer Society, August 29, 2008. Signed-off-by: Thomas Schwinge Signed-off-by: Maciej W. Rozycki Signed-off-by: Aleksandar Markovic Tested-by: Bastian Koppelmann Reviewed-by: Leon Alrae Tested-by: Leon Alrae Reviewed-by: Peter Maydell [leon.al...@imgtec.com: * cherry-picked 2 chunks from patch #2 to fix compilation warnings] Signed-off-by: Leon Alrae --- fpu/softfloat-specialize.h| 549 +++
[Qemu-devel] [PULL 07/10] target-mips: Add abs2008 flavor of .
From: Aleksandar Markovic Updated handling of instructions .. Note that legacy (pre-abs2008) ABS and NEG instructions are arithmetic (and, therefore, any NaN operand causes signaling invalid operation), while abs2008 ones are non-arithmetic, always and only changing the sign bit, even for NaN-like operands. Details on these instructions are documented in [1] p. 35 and 359. Implementation-wise, abs2008 versions are implemented without helpers, for simplicity and performance sake. [1] "MIPS Architecture For Programmers Volume II-A: The MIPS64 Instruction Set Reference Manual", Imagination Technologies LTD, Revision 6.04, November 13, 2015 Signed-off-by: Thomas Schwinge Signed-off-by: Maciej W. Rozycki Signed-off-by: Aleksandar Markovic Reviewed-by: Leon Alrae Signed-off-by: Leon Alrae --- target-mips/translate.c | 26 ++ 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index a1a9f75..661ca3a 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -1435,6 +1435,7 @@ typedef struct DisasContext { bool vp; bool cmgcr; bool mrp; +bool abs2008; } DisasContext; enum { @@ -8890,7 +8891,11 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1, TCGv_i32 fp0 = tcg_temp_new_i32(); gen_load_fpr32(ctx, fp0, fs); -gen_helper_float_abs_s(fp0, fp0); +if (ctx->abs2008) { +tcg_gen_andi_i32(fp0, fp0, 0x7fffUL); +} else { +gen_helper_float_abs_s(fp0, fp0); +} gen_store_fpr32(ctx, fp0, fd); tcg_temp_free_i32(fp0); } @@ -8909,7 +8914,11 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1, TCGv_i32 fp0 = tcg_temp_new_i32(); gen_load_fpr32(ctx, fp0, fs); -gen_helper_float_chs_s(fp0, fp0); +if (ctx->abs2008) { +tcg_gen_xori_i32(fp0, fp0, 1UL << 31); +} else { +gen_helper_float_chs_s(fp0, fp0); +} gen_store_fpr32(ctx, fp0, fd); tcg_temp_free_i32(fp0); } @@ -9380,7 +9389,11 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1, TCGv_i64 fp0 = tcg_temp_new_i64(); gen_load_fpr64(ctx, fp0, fs); -gen_helper_float_abs_d(fp0, fp0); +if (ctx->abs2008) { +tcg_gen_andi_i64(fp0, fp0, 0x7fffULL); +} else { +gen_helper_float_abs_d(fp0, fp0); +} gen_store_fpr64(ctx, fp0, fd); tcg_temp_free_i64(fp0); } @@ -9401,7 +9414,11 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1, TCGv_i64 fp0 = tcg_temp_new_i64(); gen_load_fpr64(ctx, fp0, fs); -gen_helper_float_chs_d(fp0, fp0); +if (ctx->abs2008) { +tcg_gen_xori_i64(fp0, fp0, 1ULL << 63); +} else { +gen_helper_float_chs_d(fp0, fp0); +} gen_store_fpr64(ctx, fp0, fd); tcg_temp_free_i64(fp0); } @@ -19786,6 +19803,7 @@ void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb) (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)); ctx.vp = (env->CP0_Config5 >> CP0C5_VP) & 1; ctx.mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1; +ctx.abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1; restore_cpu_state(env, &ctx); #ifdef CONFIG_USER_ONLY ctx.mem_idx = MIPS_HFLAG_UM; -- 2.7.4
[Qemu-devel] [PULL 10/10] target-mips: Add FCR31's FS bit definition
From: Aleksandar Markovic Add preprocessor definition of FCR31's FS bit, and update related code for setting this bit. Signed-off-by: Aleksandar Markovic Reviewed-by: Leon Alrae Signed-off-by: Leon Alrae --- target-mips/cpu.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/target-mips/cpu.h b/target-mips/cpu.h index bc0c905..c2da5ec 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -113,6 +113,7 @@ struct CPUMIPSFPUContext { /* fcsr */ uint32_t fcr31_rw_bitmask; uint32_t fcr31; +#define FCR31_FS 24 #define FCR31_ABS2008 19 #define FCR31_NAN2008 18 #define SET_FP_COND(num,env) do { ((env).fcr31) |= ((num) ? (1 << ((num) + 24)) : (1 << 23)); } while(0) @@ -850,7 +851,7 @@ static inline void restore_rounding_mode(CPUMIPSState *env) static inline void restore_flush_mode(CPUMIPSState *env) { -set_flush_to_zero((env->active_fpu.fcr31 & (1 << 24)) != 0, +set_flush_to_zero((env->active_fpu.fcr31 & (1 << FCR31_FS)) != 0, &env->active_fpu.fp_status); } -- 2.7.4
[Qemu-devel] [PULL 06/10] target-mips: Activate IEEE 754-2008 signaling NaN bit meaning for MSA
From: Aleksandar Markovic Function msa_reset() is updated so that flag snan_bit_is_one is properly set to 0. By applying this patch, a number of incorrect MSA behaviors that require IEEE 754-2008 compliance will be fixed. Those are behaviors that (up to the moment of applying this patch) did not get the desired functionality from SoftFloat library with respect to distinguishing between quiet and signaling NaN, getting default NaN values (both quiet and signaling), establishing if a floating point number is NaN or not, etc. Two examples: * FMAX, FMIN will now correctly detect and propagate NaNs. * FCLASS.D ans FCLASS.S will now correcty detect NaN flavors. Signed-off-by: Aleksandar Markovic Reviewed-by: Leon Alrae Signed-off-by: Leon Alrae --- target-mips/translate_init.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c index e81a831..a37d8bb 100644 --- a/target-mips/translate_init.c +++ b/target-mips/translate_init.c @@ -893,5 +893,6 @@ static void msa_reset(CPUMIPSState *env) /* clear float_status nan mode */ set_default_nan_mode(0, &env->active_tc.msa_fp_status); -set_snan_bit_is_one(1, &env->active_tc.msa_fp_status); +/* set proper signanling bit meaning ("1" means "quiet") */ +set_snan_bit_is_one(0, &env->active_tc.msa_fp_status); } -- 2.7.4
[Qemu-devel] [PULL 04/10] softfloat: Handle snan_bit_is_one == 0 in MIPS pickNaNMulAdd()
From: Aleksandar Markovic Only for Mips platform, and only for cases when snan_bit_is_one is 0, correct the order of argument comparisons in pickNaNMulAdd(). For more info, see [1], page 53, section "3.5.3 NaN Propagation". [1] "MIPS Architecture for Programmers Volume IV-j: The MIPS32 SIMD Architecture Module", Imagination Technologies LTD, Revision 1.12, February 3, 2016 Signed-off-by: Aleksandar Markovic Reviewed-by: Leon Alrae Reviewed-by: Peter Maydell [leon.al...@imgtec.com: * reworded the subject of the patch * swapped if/else code blocks to match the commit description] Signed-off-by: Leon Alrae --- fpu/softfloat-specialize.h | 41 + 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h index a1bcb46..43d0890 100644 --- a/fpu/softfloat-specialize.h +++ b/fpu/softfloat-specialize.h @@ -571,19 +571,36 @@ static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, return 3; } -/* Prefer sNaN over qNaN, in the a, b, c order. */ -if (aIsSNaN) { -return 0; -} else if (bIsSNaN) { -return 1; -} else if (cIsSNaN) { -return 2; -} else if (aIsQNaN) { -return 0; -} else if (bIsQNaN) { -return 1; +if (status->snan_bit_is_one) { +/* Prefer sNaN over qNaN, in the a, b, c order. */ +if (aIsSNaN) { +return 0; +} else if (bIsSNaN) { +return 1; +} else if (cIsSNaN) { +return 2; +} else if (aIsQNaN) { +return 0; +} else if (bIsQNaN) { +return 1; +} else { +return 2; +} } else { -return 2; +/* Prefer sNaN over qNaN, in the c, a, b order. */ +if (cIsSNaN) { +return 2; +} else if (aIsSNaN) { +return 0; +} else if (bIsSNaN) { +return 1; +} else if (cIsQNaN) { +return 2; +} else if (aIsQNaN) { +return 0; +} else { +return 1; +} } } #elif defined(TARGET_PPC) -- 2.7.4
[Qemu-devel] [PULL 05/10] linux-user: Update preprocessor constants for Mips-specific e_flags bits
From: Aleksandar Markovic Missing values EF_MIPS_FP64 and EF_MIPS_NAN2008 added. Signed-off-by: Thomas Schwinge Signed-off-by: Maciej W. Rozycki Signed-off-by: Aleksandar Markovic Reviewed-by: Leon Alrae Reviewed-by: Peter Maydell Signed-off-by: Leon Alrae --- include/elf.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/elf.h b/include/elf.h index 8533b2a..745739a 100644 --- a/include/elf.h +++ b/include/elf.h @@ -53,6 +53,8 @@ typedef int64_t Elf64_Sxword; #define EF_MIPS_OPTIONS_FIRST 0x0080 #define EF_MIPS_32BITMODE 0x0100 #define EF_MIPS_ABI0xf000 +#define EF_MIPS_FP64 0x0200 +#define EF_MIPS_NAN2008 0x0400 #define EF_MIPS_ARCH 0xf000 /* These constants define the different elf file types */ -- 2.7.4
[Qemu-devel] [PULL 08/10] target-mips: Add nan2008 flavor of ..
From: Aleksandar Markovic New set of helpers for handling nan2008-syle versions of instructions .., for Mips R6. All involved instructions have float operand and integer result. Their core functionality is implemented via invocations of appropriate SoftFloat functions. The problematic cases are when the operand is a NaN, and also when the operand (float) is out of the range of the result. Here one can distinguish three cases: CASE MIPS-A: (FCR31.NAN2008 == 1) 1. Operand is a NaN, result should be 0; 2. Operand is larger than INT_MAX, result should be INT_MAX; 3. Operand is smaller than INT_MIN, result should be INT_MIN. CASE MIPS-B: (FCR31.NAN2008 == 0) 1. Operand is a NaN, result should be INT_MAX; 2. Operand is larger than INT_MAX, result should be INT_MAX; 3. Operand is smaller than INT_MIN, result should be INT_MAX. CASE SoftFloat: 1. Operand is a NaN, result is INT_MAX; 2. Operand is larger than INT_MAX, result is INT_MAX; 3. Operand is smaller than INT_MIN, result is INT_MIN. Current implementation of .. implements case MIPS-B. This patch relates to case MIPS-A. For case MIPS-A, only return value for NaN-operands should be corrected after appropriate SoftFloat library function is called. Related MSA instructions FTRUNC_S and FTINT_S already handle well all cases, in the fashion similar to the code from this patch. Signed-off-by: Aleksandar Markovic Reviewed-by: Leon Alrae [leon.al...@imgtec.com: * removed a statement from the description which caused slight confusion] Signed-off-by: Leon Alrae --- target-mips/helper.h| 18 +-- target-mips/op_helper.c | 369 +--- target-mips/translate.c | 122 +--- 3 files changed, 461 insertions(+), 48 deletions(-) diff --git a/target-mips/helper.h b/target-mips/helper.h index 8546177..666936c 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -207,8 +207,6 @@ DEF_HELPER_4(ctc1, void, env, tl, i32, i32) DEF_HELPER_2(float_cvtd_s, i64, env, i32) DEF_HELPER_2(float_cvtd_w, i64, env, i32) DEF_HELPER_2(float_cvtd_l, i64, env, i64) -DEF_HELPER_2(float_cvtl_d, i64, env, i64) -DEF_HELPER_2(float_cvtl_s, i64, env, i32) DEF_HELPER_2(float_cvtps_pw, i64, env, i64) DEF_HELPER_2(float_cvtpw_ps, i64, env, i64) DEF_HELPER_2(float_cvts_d, i32, env, i64) @@ -216,8 +214,6 @@ DEF_HELPER_2(float_cvts_w, i32, env, i32) DEF_HELPER_2(float_cvts_l, i32, env, i64) DEF_HELPER_2(float_cvts_pl, i32, env, i32) DEF_HELPER_2(float_cvts_pu, i32, env, i32) -DEF_HELPER_2(float_cvtw_s, i32, env, i32) -DEF_HELPER_2(float_cvtw_d, i32, env, i64) DEF_HELPER_3(float_addr_ps, i64, env, i64, i64) DEF_HELPER_3(float_mulr_ps, i64, env, i64, i64) @@ -242,14 +238,20 @@ FOP_PROTO(mina) #undef FOP_PROTO #define FOP_PROTO(op)\ -DEF_HELPER_2(float_ ## op ## l_s, i64, env, i32) \ -DEF_HELPER_2(float_ ## op ## l_d, i64, env, i64) \ -DEF_HELPER_2(float_ ## op ## w_s, i32, env, i32) \ -DEF_HELPER_2(float_ ## op ## w_d, i32, env, i64) +DEF_HELPER_2(float_ ## op ## _l_s, i64, env, i32) \ +DEF_HELPER_2(float_ ## op ## _l_d, i64, env, i64) \ +DEF_HELPER_2(float_ ## op ## _w_s, i32, env, i32) \ +DEF_HELPER_2(float_ ## op ## _w_d, i32, env, i64) +FOP_PROTO(cvt) FOP_PROTO(round) FOP_PROTO(trunc) FOP_PROTO(ceil) FOP_PROTO(floor) +FOP_PROTO(cvt_2008) +FOP_PROTO(round_2008) +FOP_PROTO(trunc_2008) +FOP_PROTO(ceil_2008) +FOP_PROTO(floor_2008) #undef FOP_PROTO #define FOP_PROTO(op)\ diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 97dffa2..7f6e821 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -2447,6 +2447,7 @@ void mips_cpu_unassigned_access(CPUState *cs, hwaddr addr, #define FLOAT_TWO32 make_float32(1 << 30) #define FLOAT_TWO64 make_float64(1ULL << 62) + #define FP_TO_INT32_OVERFLOW 0x7fff #define FP_TO_INT64_OVERFLOW 0x7fffULL @@ -2682,7 +2683,7 @@ uint64_t helper_float_cvtd_l(CPUMIPSState *env, uint64_t dt0) return fdt2; } -uint64_t helper_float_cvtl_d(CPUMIPSState *env, uint64_t fdt0) +uint64_t helper_float_cvt_l_d(CPUMIPSState *env, uint64_t fdt0) { uint64_t dt2; @@ -2695,7 +2696,7 @@ uint64_t helper_float_cvtl_d(CPUMIPSState *env, uint64_t fdt0) return dt2; } -uint64_t helper_float_cvtl_s(CPUMIPSState *env, uint32_t fst0) +uint64_t helper_float_cvt_l_s(CPUMIPSState *env, uint32_t fst0) { uint64_t dt2; @@ -2790,7 +2791,7 @@ uint32_t helper_float_cvts_pu(CPUMIPSState *env, uint32_t wth0) return wt2; } -uint32_t helper_float_cvtw_s(CPUMIPSState *env, uint32_t fst0) +uint32_t helper_float_cvt_w_s(CPUMIPSState *env, uint32_t fst0) { uint32_t wt2; @@ -2803,7 +2804,7 @@ uint32_t helper_float_cvtw_s(CPUMIPSState *env, uint32_t fst0) return wt2; } -uint32_t helper_float_cvtw_d(CPUMIPSState *env, uint64_t fdt0) +uint32_t helper_float_cvt_w_d(CPUMIPSState *env, uint64_t fdt0) { uint32_t wt2;
[Qemu-devel] [PULL 09/10] target-mips: Implement FCR31's R/W bitmask and related functionalities
From: Aleksandar Markovic This patch implements read and write access rules for Mips floating point control and status register (FCR31). The change can be divided into following parts: - Add fields that will keep FCR31's R/W bitmask in procesor definitions and processor float_status structure. - Add appropriate value for FCR31's R/W bitmask for each supported processor. - Add function for setting snan_bit_is_one, and integrate it in appropriate places. - Modify handling of CTC1 (case 31) instruction to use FCR31's R/W bitmask. - Modify handling user mode executables for Mips, in relation to the bit EF_MIPS_NAN2008 from ELF header, that is in turn related to reading and writing to FCR31. - Modify gdb behavior in relation to FCR31. Signed-off-by: Thomas Schwinge Signed-off-by: Maciej W. Rozycki Signed-off-by: Aleksandar Markovic Reviewed-by: Leon Alrae Signed-off-by: Leon Alrae --- linux-user/main.c| 14 ++ target-mips/cpu.h| 8 target-mips/gdbstub.c| 8 +++- target-mips/op_helper.c | 14 +++--- target-mips/translate.c | 5 ++--- target-mips/translate_init.c | 26 ++ 6 files changed, 56 insertions(+), 19 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index fd88e22..78d8d04 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -4687,6 +4687,20 @@ int main(int argc, char **argv, char **envp) if (regs->cp0_epc & 1) { env->hflags |= MIPS_HFLAG_M16; } +if (((info->elf_flags & EF_MIPS_NAN2008) != 0) != +((env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) != 0)) { +if ((env->active_fpu.fcr31_rw_bitmask & + (1 << FCR31_NAN2008)) == 0) { +fprintf(stderr, "ELF binary's NaN mode not supported by CPU\n"); +exit(1); +} +if ((info->elf_flags & EF_MIPS_NAN2008) != 0) { +env->active_fpu.fcr31 |= (1 << FCR31_NAN2008); +} else { +env->active_fpu.fcr31 &= ~(1 << FCR31_NAN2008); +} +restore_snan_bit_mode(env); +} } #elif defined(TARGET_OPENRISC) { diff --git a/target-mips/cpu.h b/target-mips/cpu.h index b593f3b..bc0c905 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -111,6 +111,7 @@ struct CPUMIPSFPUContext { #define FCR0_PRID 8 #define FCR0_REV 0 /* fcsr */ +uint32_t fcr31_rw_bitmask; uint32_t fcr31; #define FCR31_ABS2008 19 #define FCR31_NAN2008 18 @@ -853,10 +854,17 @@ static inline void restore_flush_mode(CPUMIPSState *env) &env->active_fpu.fp_status); } +static inline void restore_snan_bit_mode(CPUMIPSState *env) +{ +set_snan_bit_is_one((env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) == 0, +&env->active_fpu.fp_status); +} + static inline void restore_fp_status(CPUMIPSState *env) { restore_rounding_mode(env); restore_flush_mode(env); +restore_snan_bit_mode(env); } static inline void restore_msa_fp_status(CPUMIPSState *env) diff --git a/target-mips/gdbstub.c b/target-mips/gdbstub.c index 2707ff5..7c68228 100644 --- a/target-mips/gdbstub.c +++ b/target-mips/gdbstub.c @@ -90,11 +90,9 @@ int mips_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) if (env->CP0_Config1 & (1 << CP0C1_FP) && n >= 38 && n < 72) { switch (n) { case 70: -env->active_fpu.fcr31 = tmp & 0xFF83; -/* set rounding mode */ -restore_rounding_mode(env); -/* set flush-to-zero mode */ -restore_flush_mode(env); +env->active_fpu.fcr31 = (tmp & env->active_fpu.fcr31_rw_bitmask) | + (env->active_fpu.fcr31 & ~(env->active_fpu.fcr31_rw_bitmask)); +restore_fp_status(env); break; case 71: /* FIR is read-only. Ignore writes. */ diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 7f6e821..69daade 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -2575,21 +2575,13 @@ void helper_ctc1(CPUMIPSState *env, target_ulong arg1, uint32_t fs, uint32_t rt) ((arg1 & 0x4) << 22); break; case 31: -if (env->insn_flags & ISA_MIPS32R6) { -uint32_t mask = 0xfefc; -env->active_fpu.fcr31 = (arg1 & ~mask) | -(env->active_fpu.fcr31 & mask); -} else if (!(arg1 & 0x007c)) { -env->active_fpu.fcr31 = arg1; -} +env->active_fpu.fcr31 = (arg1 & env->active_fpu.fcr31_rw_bitmask) | + (env->active_fpu.fcr31 & ~(env->active_fpu.fcr31_rw_bit
[Qemu-devel] [PULL 02/10] softfloat: Clean code format in fpu/softfloat-specialize.h
From: Aleksandar Markovic fpu/softfloat-specialize.h is the most critical file in SoftFloat library, since it handles numerous differences between platforms in relation to floating point arithmetics. This patch makes the code in this file more consistent format-wise, and hopefully easier to debug and maintain. Signed-off-by: Aleksandar Markovic Reviewed-by: Peter Maydell Signed-off-by: Leon Alrae --- fpu/softfloat-specialize.h | 57 +++--- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h index 39095e5..981d665 100644 --- a/fpu/softfloat-specialize.h +++ b/fpu/softfloat-specialize.h @@ -273,7 +273,7 @@ static commonNaNT float16ToCommonNaN(float16 a, float_status *status) } z.sign = float16_val(a) >> 15; z.low = 0; -z.high = ((uint64_t) float16_val(a))<<54; +z.high = ((uint64_t) float16_val(a)) << 54; return z; } @@ -284,7 +284,7 @@ static commonNaNT float16ToCommonNaN(float16 a, float_status *status) static float16 commonNaNToFloat16(commonNaNT a, float_status *status) { -uint16_t mantissa = a.high>>54; +uint16_t mantissa = a.high >> 54; if (status->default_nan_mode) { return float16_default_nan(status); @@ -372,9 +372,9 @@ static commonNaNT float32ToCommonNaN(float32 a, float_status *status) if (float32_is_signaling_nan(a, status)) { float_raise(float_flag_invalid, status); } -z.sign = float32_val(a)>>31; +z.sign = float32_val(a) >> 31; z.low = 0; -z.high = ( (uint64_t) float32_val(a) )<<41; +z.high = ((uint64_t)float32_val(a)) << 41; return z; } @@ -385,7 +385,7 @@ static commonNaNT float32ToCommonNaN(float32 a, float_status *status) static float32 commonNaNToFloat32(commonNaNT a, float_status *status) { -uint32_t mantissa = a.high>>41; +uint32_t mantissa = a.high >> 41; if (status->default_nan_mode) { return float32_default_nan(status); @@ -393,7 +393,7 @@ static float32 commonNaNToFloat32(commonNaNT a, float_status *status) if (mantissa) { return make_float32( -( ( (uint32_t) a.sign )<<31 ) | 0x7F80 | ( a.high>>41 ) ); +(((uint32_t)a.sign) << 31) | 0x7F80 | (a.high >> 41)); } else { return float32_default_nan(status); } @@ -498,11 +498,10 @@ static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, return aIsLargerSignificand ? 0 : 1; } return bIsQNaN ? 1 : 0; -} -else if (aIsQNaN) { -if (bIsSNaN || !bIsQNaN) +} else if (aIsQNaN) { +if (bIsSNaN || !bIsQNaN) { return 0; -else { +} else { return aIsLargerSignificand ? 0 : 1; } } else { @@ -645,9 +644,9 @@ static float32 propagateFloat32NaN(float32 a, float32 b, float_status *status) return float32_default_nan(status); } -if ((uint32_t)(av<<1) < (uint32_t)(bv<<1)) { +if ((uint32_t)(av << 1) < (uint32_t)(bv << 1)) { aIsLargerSignificand = 0; -} else if ((uint32_t)(bv<<1) < (uint32_t)(av<<1)) { +} else if ((uint32_t)(bv << 1) < (uint32_t)(av << 1)) { aIsLargerSignificand = 1; } else { aIsLargerSignificand = (av < bv) ? 1 : 0; @@ -789,9 +788,9 @@ static commonNaNT float64ToCommonNaN(float64 a, float_status *status) if (float64_is_signaling_nan(a, status)) { float_raise(float_flag_invalid, status); } -z.sign = float64_val(a)>>63; +z.sign = float64_val(a) >> 63; z.low = 0; -z.high = float64_val(a)<<12; +z.high = float64_val(a) << 12; return z; } @@ -802,7 +801,7 @@ static commonNaNT float64ToCommonNaN(float64 a, float_status *status) static float64 commonNaNToFloat64(commonNaNT a, float_status *status) { -uint64_t mantissa = a.high>>12; +uint64_t mantissa = a.high >> 12; if (status->default_nan_mode) { return float64_default_nan(status); @@ -810,9 +809,9 @@ static float64 commonNaNToFloat64(commonNaNT a, float_status *status) if (mantissa) { return make_float64( - ( ( (uint64_t) a.sign )<<63 ) -| LIT64( 0x7FF0 ) -| ( a.high>>12 )); + (((uint64_t) a.sign) << 63) +| LIT64(0x7FF0) +| (a.high >> 12)); } else { return float64_default_nan(status); } @@ -845,9 +844,9 @@ static float64 propagateFloat64NaN(float64 a, float64 b, float_status *status) return float64_default_nan(status); } -if ((uint64_t)(av<<1) < (uint64_t)(bv<<1)) { +if ((uint64_t)(av << 1) < (uint64_t)(bv << 1
[Qemu-devel] [PULL 03/10] softfloat: For Mips only, correct default NaN values
From: Aleksandar Markovic Only for Mips platform, and only for cases when snan_bit_is_one is 0, correct default NaN values (in their 16-, 32-, and 64-bit flavors). For more info, see [1], page 84, Table 6.3 "Value Supplied When a New Quiet NaN Is Created", and [2], page 52, Table 3.7 "Default NaN Encodings". [1] "MIPS Architecture For Programmers Volume II-A: The MIPS64 Instruction Set Reference Manual", Imagination Technologies LTD, Revision 6.04, November 13, 2015 [2] "MIPS Architecture for Programmers Volume IV-j: The MIPS32 SIMD Architecture Module", Imagination Technologies LTD, Revision 1.12, February 3, 2016 Signed-off-by: Aleksandar Markovic Reviewed-by: Leon Alrae Reviewed-by: Peter Maydell Signed-off-by: Leon Alrae --- fpu/softfloat-specialize.h | 12 1 file changed, 12 insertions(+) diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h index 981d665..a1bcb46 100644 --- a/fpu/softfloat-specialize.h +++ b/fpu/softfloat-specialize.h @@ -97,7 +97,11 @@ float16 float16_default_nan(float_status *status) if (status->snan_bit_is_one) { return const_float16(0x7DFF); } else { +#if defined(TARGET_MIPS) +return const_float16(0x7E00); +#else return const_float16(0xFE00); +#endif } #endif } @@ -116,7 +120,11 @@ float32 float32_default_nan(float_status *status) if (status->snan_bit_is_one) { return const_float32(0x7FBF); } else { +#if defined(TARGET_MIPS) +return const_float32(0x7FC0); +#else return const_float32(0xFFC0); +#endif } #endif } @@ -135,7 +143,11 @@ float64 float64_default_nan(float_status *status) if (status->snan_bit_is_one) { return const_float64(LIT64(0x7FF7)); } else { +#if defined(TARGET_MIPS) +return const_float64(LIT64(0x7FF8)); +#else return const_float64(LIT64(0xFFF8)); +#endif } #endif } -- 2.7.4
[Qemu-devel] [PULL 00/10] target-mips queue
Hi, This pull request contains patches from Aleksandar which unlock the IEEE 754-2008 support for MIPS. Thanks, Leon Cc: Peter Maydell Cc: Aurelien Jarno The following changes since commit c7288767523f6510cf557707d3eb5e78e519b90d: Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.7-20160623' into staging (2016-06-23 11:53:14 +0100) are available in the git repository at: git://github.com/lalrae/qemu.git tags/mips-20160624 for you to fetch changes up to 77be419980114d75605811e1681115d0919cfa1a: target-mips: Add FCR31's FS bit definition (2016-06-24 13:43:53 +0100) MIPS patches 2016-06-24 Changes: * support IEEE 754-2008 in MIPS CPUs Aleksandar Markovic (10): softfloat: Implement run-time-configurable meaning of signaling NaN bit softfloat: Clean code format in fpu/softfloat-specialize.h softfloat: For Mips only, correct default NaN values softfloat: Handle snan_bit_is_one == 0 in MIPS pickNaNMulAdd() linux-user: Update preprocessor constants for Mips-specific e_flags bits target-mips: Activate IEEE 754-2008 signaling NaN bit meaning for MSA target-mips: Add abs2008 flavor of . target-mips: Add nan2008 flavor of .. target-mips: Implement FCR31's R/W bitmask and related functionalities target-mips: Add FCR31's FS bit definition fpu/softfloat-specialize.h| 659 +- fpu/softfloat.c | 172 +-- include/elf.h | 2 + include/fpu/softfloat.h | 45 +-- linux-user/main.c | 14 + target-arm/helper-a64.c | 14 +- target-arm/helper.c | 40 +-- target-m68k/helper.c | 6 +- target-microblaze/op_helper.c | 6 +- target-mips/cpu.h | 16 +- target-mips/gdbstub.c | 8 +- target-mips/helper.h | 22 +- target-mips/msa_helper.c | 88 +++--- target-mips/op_helper.c | 400 ++--- target-mips/translate.c | 156 -- target-mips/translate_init.c | 29 ++ target-ppc/fpu_helper.c | 120 target-s390x/fpu_helper.c | 28 +- target-s390x/helper.h | 6 +- target-s390x/translate.c | 6 +- target-sh4/cpu.c | 1 + target-unicore32/cpu.c| 2 + 22 files changed, 1167 insertions(+), 673 deletions(-)
Re: [Qemu-devel] [PATCH v9 00/10] IEEE 754-2008 support for Mips
On Thu, Jun 23, 2016 at 04:46:14PM +0100, Peter Maydell wrote: > On 10 June 2016 at 10:57, Aleksandar Markovic > wrote: > > From: Aleksandar Markovic > > > > This patch series provides number of IEEE 754-2008-related features to > > Mips platform. It addresses the most sensitive changes that require > > modification of SoftFloat library, also used by most other platforms. > > > > In order to make develpoment, testing, and integration easier, the patch > > is split into two distinct parts: > > > >1. Part 1 (patches 1/10, 2/10, 3/10, 4/10, 5/10) that does not change any > > calculation or behavior on any platform (and, for that matter, even on > > Mips platform). Its sole purpose is to address platform independant > > issues in a non-invasive manner, and to make Part 2 possible. > > > >2. Part 2 (patches 6/10, 7/10, 8/10, 9/10, 10/10) that sets some Mips > > processors to use provisions from Part 1, and additionally implements > > number of IEEE 754-2008-related features for Mips, while, at the same > > time, mainly dealing with files located in directory target-mips only. > > Hi. I've reviewed the patches in Part 1, and I'm happy with them > apart from a few trivial things. I'm not going to look at Part 2 > since it's pretty MIPS specific. > > I'm assuming that Leon will take these via the MIPS tree. Leon, > it's up to you whether you're happy to fix up the minor things I > raised when you put the patches into your tree or if you'd > prefer to have Aleksandar respin and resend the patchset. No need to respin; I'll fix these issues while applying to target-mips queue. > Either way, it would be good to get these into a pull request > by Monday since softfreeze deadline is nearly here... Sure, I'll send the pullreq by then. Thanks, Leon
Re: [Qemu-devel] [PATCH v6 8/9] target-mips: Add nan2008 flavor of ..
On Fri, Jun 10, 2016 at 09:12:12PM +0100, Maciej W. Rozycki wrote: > On Fri, 10 Jun 2016, Aleksandar Markovic wrote: > > > The changes that make QEMU behavior the same as hardware behavior (in > > relation to CEIL, CVT, FLOOR, ROUND, TRUNC Mips instructions) are > > already contained in this patch. > > Good, however that means that you've really combined two logically > separate changes into a single patch: > > 1. A bug fix for SoftFloat legacy-NaN (original) MIPS support, which has >been there probably since forever (i.e. since the MIPS target was added >to QEMU). I've just done another round of review and as far as I can tell these patches don't modify the legacy-NaN MIPS behaviour. I believe Aleksandar was referring to new functionality (i.e. 2008 NaN) only. Regards, Leon > > 2. A new feature for 2008-NaN MIPS support. > > To me it really looks like the two need to be separate patches, with the > bug fix applied first (or among any other bug fixes at the beginning) in > the patch set, or even as a separate change marked as a prerequisite for > the rest of the changes. > > The bug fix will then be self-contained and more prominently exposed, > rather than being buried among feature additions. It can then be > independently reviewed and likely more easily accepted as long as it is > technically correct. It can also be cherry-picked and backported easily > if necessary, perhaps outside the upstream tree. > > Review of the new feature set can then follow, once the bug(s) have been > fixed. > > > I just mentioned Mips-A / Mips-B / SoftFloat differences as an > > explanation/observation related to the change in this patch. > > Maybe it's just myself, but from your description I got the impression > that your change preserves the status quo and the explanation merely > serves the purpose of documenting it. Please consider rewriting it such > that it is unambiguous that the SoftFloat bug is being fixed with your > change. > > Obviously once you've made the bug fix a separate change, it'll become > unambiguous naturally, as then you won't have the 2008-NaN feature along > it obfuscating the picture. > > Maciej
Re: [Qemu-devel] [PATCH v9 10/10] target-mips: Add FCR31's FS bit definition
On Fri, Jun 10, 2016 at 11:57:37AM +0200, Aleksandar Markovic wrote: > From: Aleksandar Markovic > > Add preprocessor definition of FCR31's FS bit, and update related > code for setting this bit. > > Signed-off-by: Aleksandar Markovic > --- > target-mips/cpu.h | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) Reviewed-by: Leon Alrae
Re: [Qemu-devel] [PATCH v9 01/10] softfloat: Implement run-time-configurable meaning of signaling NaN bit
not needed. > > [1] "IEEE Standard for Floating-Point Arithmetic", > IEEE Computer Society, August 29, 2008. > > Tested-by: Bastian Koppelmann (TriCore part) > Signed-off-by: Thomas Schwinge > Signed-off-by: Maciej W. Rozycki > Signed-off-by: Aleksandar Markovic > --- > fpu/softfloat-specialize.h| 535 > -- > fpu/softfloat.c | 172 ++ > include/fpu/softfloat.h | 45 ++-- > target-arm/helper-a64.c | 14 +- > target-arm/helper.c | 40 ++-- > target-m68k/helper.c | 6 +- > target-microblaze/op_helper.c | 6 +- > target-mips/cpu.h | 5 + > target-mips/helper.h | 4 +- > target-mips/msa_helper.c | 88 +++ > target-mips/op_helper.c | 17 +- > target-mips/translate.c | 5 +- > target-mips/translate_init.c | 2 + > target-ppc/fpu_helper.c | 120 +----- > target-s390x/fpu_helper.c | 28 ++- > target-s390x/helper.h | 6 +- > target-s390x/translate.c | 6 +- > target-sh4/cpu.c | 1 + > target-unicore32/cpu.c| 2 + > 19 files changed, 547 insertions(+), 555 deletions(-) Looks good to me (plus I ran my regression tests for MIPS): Reviewed-by: Leon Alrae Tested-by: Leon Alrae Thanks, Leon
Re: [Qemu-devel] [PATCH v9 09/10] target-mips: Implement FCR31's R/W bitmask and related functionalities
On Fri, Jun 10, 2016 at 11:57:36AM +0200, Aleksandar Markovic wrote: > From: Aleksandar Markovic > > This patch implements read and write access rules for Mips floating > point control and status register (FCR31). The change can be divided > into following parts: > > - Add fields that will keep FCR31's R/W bitmask in procesor > definitions and processor float_status structure. > > - Add appropriate value for FCR31's R/W bitmask for each supported > processor. > > - Add function for setting snan_bit_is_one, and integrate it in > appropriate places. > > - Modify handling of CTC1 (case 31) instruction to use FCR31's R/W > bitmask. > > - Modify handling user mode executables for Mips, in relation to the > bit EF_MIPS_NAN2008 from ELF header, that is in turn related to > reading and writing to FCR31. > > - Modify gdb behavior in relation to FCR31. > > Signed-off-by: Thomas Schwinge > Signed-off-by: Maciej W. Rozycki > Signed-off-by: Aleksandar Markovic > --- > linux-user/main.c| 14 ++ > target-mips/cpu.h| 8 > target-mips/gdbstub.c| 8 +++- > target-mips/op_helper.c | 14 +++--- > target-mips/translate.c | 5 ++--- > target-mips/translate_init.c | 26 ++ > 6 files changed, 56 insertions(+), 19 deletions(-) Reviewed-by: Leon Alrae
[Qemu-devel] [PATCH 3/3] hw/mips_cmgcr: implement RESET_BASE register in CM GCR
Implement RESET_BASE register which is local to each VP and a write to it changes VP's reset exception base. Also, add OTHER register to allow a software running on one VP to access other VP's local registers. Guest can use this mechanism to specify custom address from which a VP will start execution. Signed-off-by: Leon Alrae --- hw/misc/mips_cmgcr.c | 54 +++- include/hw/misc/mips_cmgcr.h | 18 +++ 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/hw/misc/mips_cmgcr.c b/hw/misc/mips_cmgcr.c index e6cf17d..b3ba166 100644 --- a/hw/misc/mips_cmgcr.c +++ b/hw/misc/mips_cmgcr.c @@ -59,6 +59,8 @@ static inline void update_gic_base(MIPSGCRState *gcr, uint64_t val) static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size) { MIPSGCRState *gcr = (MIPSGCRState *) opaque; +MIPSGCRVPState *current_vps = &gcr->vps[current_cpu->cpu_index]; +MIPSGCRVPState *other_vps = &gcr->vps[current_vps->other]; switch (addr) { /* Global Control Block Register */ @@ -85,8 +87,14 @@ static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size) case MIPS_COCB_OFS + GCR_CL_CONFIG_OFS: /* Set PVP to # of VPs - 1 */ return gcr->num_vps - 1; +case MIPS_CLCB_OFS + GCR_CL_RESETBASE_OFS: +return current_vps->reset_base; +case MIPS_COCB_OFS + GCR_CL_RESETBASE_OFS: +return other_vps->reset_base; case MIPS_CLCB_OFS + GCR_CL_OTHER_OFS: -return 0; +return current_vps->other; +case MIPS_COCB_OFS + GCR_CL_OTHER_OFS: +return other_vps->other; default: qemu_log_mask(LOG_UNIMP, "Read %d bytes at GCR offset 0x%" HWADDR_PRIx "\n", size, addr); @@ -95,10 +103,18 @@ static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size) return 0; } +static inline target_ulong get_exception_base(MIPSGCRVPState *vps) +{ +/* TODO: BEV_BASE and SELECT_BEV */ +return (int32_t)(vps->reset_base & GCR_CL_RESET_BASE_RESETBASE_MSK); +} + /* Write GCR registers */ static void gcr_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) { MIPSGCRState *gcr = (MIPSGCRState *)opaque; +MIPSGCRVPState *current_vps = &gcr->vps[current_cpu->cpu_index]; +MIPSGCRVPState *other_vps = &gcr->vps[current_vps->other]; switch (addr) { case GCR_GIC_BASE_OFS: @@ -107,6 +123,26 @@ static void gcr_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) case GCR_CPC_BASE_OFS: update_cpc_base(gcr, data); break; +case MIPS_CLCB_OFS + GCR_CL_RESETBASE_OFS: +current_vps->reset_base = data & GCR_CL_RESET_BASE_MSK; +cpu_set_exception_base(current_cpu->cpu_index, + get_exception_base(current_vps)); +break; +case MIPS_COCB_OFS + GCR_CL_RESETBASE_OFS: +other_vps->reset_base = data & GCR_CL_RESET_BASE_MSK; +cpu_set_exception_base(current_vps->other, + get_exception_base(other_vps)); +break; +case MIPS_CLCB_OFS + GCR_CL_OTHER_OFS: +if ((data & GCR_CL_OTHER_MSK) < gcr->num_vps) { +current_vps->other = data & GCR_CL_OTHER_MSK; +} +break; +case MIPS_COCB_OFS + GCR_CL_OTHER_OFS: +if ((data & GCR_CL_OTHER_MSK) < gcr->num_vps) { +other_vps->other = data & GCR_CL_OTHER_MSK; +} +break; default: qemu_log_mask(LOG_UNIMP, "Write %d bytes at GCR offset 0x%" HWADDR_PRIx " 0x%" PRIx64 "\n", size, addr, data); @@ -148,9 +184,16 @@ static void mips_gcr_init(Object *obj) static void mips_gcr_reset(DeviceState *dev) { MIPSGCRState *s = MIPS_GCR(dev); +int i; update_gic_base(s, 0); update_cpc_base(s, 0); + +for (i = 0; i < s->num_vps; i++) { +s->vps[i].other = 0; +s->vps[i].reset_base = 0xBFC0 & GCR_CL_RESET_BASE_MSK; +cpu_set_exception_base(i, get_exception_base(&s->vps[i])); +} } static const VMStateDescription vmstate_mips_gcr = { @@ -170,12 +213,21 @@ static Property mips_gcr_properties[] = { DEFINE_PROP_END_OF_LIST(), }; +static void mips_gcr_realize(DeviceState *dev, Error **errp) +{ +MIPSGCRState *s = MIPS_GCR(dev); + +/* Create local set of registers for each VP */ +s->vps = g_new(MIPSGCRVPState, s->num_vps); +} + static void mips_gcr_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->props = mips_gcr_properties; dc->vmsd = &vmstate_mips_gcr; dc->reset = mips_gcr_reset; +dc->realize = mips_gcr_realize; } static const TypeInfo mips_gcr_info = { diff --git a/include/hw/misc/mips_cmgcr.h b/include/hw/mi
[Qemu-devel] [PATCH 1/3] target-mips: add exception base to MIPS CPU
Replace hardcoded 0xbfc0 with exception_base which is initialized with this default address so there is no functional change here. However, it is now exposed and consequently it will be possible to modify it from outside of the CPU. Signed-off-by: Leon Alrae --- target-mips/cpu.h | 2 ++ target-mips/helper.c| 6 +++--- target-mips/translate.c | 9 - 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 4ce9d47..2db010f 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -614,6 +614,7 @@ struct CPUMIPSState { void *irq[8]; QEMUTimer *timer; /* Internal timer */ MemoryRegion *itc_tag; /* ITC Configuration Tags */ +target_ulong exception_base; /* ExceptionBase input to the core */ }; /** @@ -807,6 +808,7 @@ int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc); #define cpu_init(cpu_model) CPU(cpu_mips_init(cpu_model)) bool cpu_supports_cps_smp(const char *cpu_model); +void cpu_set_exception_base(int vp_index, target_ulong address); /* TODO QOM'ify CPU reset and remove */ void cpu_state_reset(CPUMIPSState *s); diff --git a/target-mips/helper.c b/target-mips/helper.c index 65fbef0..1402ff0 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -640,7 +640,7 @@ void mips_cpu_do_interrupt(CPUState *cs) /* EJTAG probe trap enable is not implemented... */ if (!(env->CP0_Status & (1 << CP0St_EXL))) env->CP0_Cause &= ~(1U << CP0Ca_BD); -env->active_tc.PC = (int32_t)0xBFC00480; +env->active_tc.PC = env->exception_base + 0x480; set_hflags_for_handler(env); break; case EXCP_RESET: @@ -667,7 +667,7 @@ void mips_cpu_do_interrupt(CPUState *cs) env->hflags &= ~(MIPS_HFLAG_KSU); if (!(env->CP0_Status & (1 << CP0St_EXL))) env->CP0_Cause &= ~(1U << CP0Ca_BD); -env->active_tc.PC = (int32_t)0xBFC0; +env->active_tc.PC = env->exception_base; set_hflags_for_handler(env); break; case EXCP_EXT_INTERRUPT: @@ -849,7 +849,7 @@ void mips_cpu_do_interrupt(CPUState *cs) } env->hflags &= ~MIPS_HFLAG_BMASK; if (env->CP0_Status & (1 << CP0St_BEV)) { -env->active_tc.PC = (int32_t)0xBFC00200; +env->active_tc.PC = env->exception_base + 0x200; } else { env->active_tc.PC = (int32_t)(env->CP0_EBase & ~0x3ff); } diff --git a/target-mips/translate.c b/target-mips/translate.c index f420680..c0aec42 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -20068,6 +20068,7 @@ MIPSCPU *cpu_mips_init(const char *cpu_model) cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU)); env = &cpu->env; env->cpu_model = def; +env->exception_base = (int32_t)0xBFC0; #ifndef CONFIG_USER_ONLY mmu_init(env, def); @@ -20090,6 +20091,12 @@ bool cpu_supports_cps_smp(const char *cpu_model) return (def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0; } +void cpu_set_exception_base(int vp_index, target_ulong address) +{ +MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index)); +vp->env.exception_base = address; +} + void cpu_state_reset(CPUMIPSState *env) { MIPSCPU *cpu = mips_env_get_cpu(env); @@ -20179,7 +20186,7 @@ void cpu_state_reset(CPUMIPSState *env) } else { env->CP0_ErrorEPC = env->active_tc.PC; } -env->active_tc.PC = (int32_t)0xBFC0; +env->active_tc.PC = env->exception_base; env->CP0_Random = env->tlb->nb_tlb - 1; env->tlb->tlb_in_use = env->tlb->nb_tlb; env->CP0_Wired = 0; -- 2.7.4
[Qemu-devel] [PATCH 2/3] hw/mips_cpc: make VP correctly start from the reset vector
When VP enters the Run state it starts execution from the reset vector. Currently used CPU_INTERRUPT_WAKE does not do that if reset exception base has been modified. Therefore fix that by simply resetting given VP. Drop the usage of CPU_INTERRUPT_WAKE also in VP_STOP and instead raise the CPU_INTERRUPT_HALT to halt a VP. Signed-off-by: Leon Alrae --- hw/misc/mips_cpc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hw/misc/mips_cpc.c b/hw/misc/mips_cpc.c index e6a35dd..6d34574 100644 --- a/hw/misc/mips_cpc.c +++ b/hw/misc/mips_cpc.c @@ -37,7 +37,7 @@ static void cpc_run_vp(MIPSCPCState *cpc, uint64_t vp_run) CPU_FOREACH(cs) { uint64_t i = 1ULL << cs->cpu_index; if (i & vp_run & ~cpc->vp_running) { -cpu_interrupt(cs, CPU_INTERRUPT_WAKE); +cpu_reset(cs); cpc->vp_running |= i; } } @@ -50,8 +50,7 @@ static void cpc_stop_vp(MIPSCPCState *cpc, uint64_t vp_stop) CPU_FOREACH(cs) { uint64_t i = 1ULL << cs->cpu_index; if (i & vp_stop & cpc->vp_running) { -cs->halted = 1; -cpu_reset_interrupt(cs, CPU_INTERRUPT_WAKE); +cpu_interrupt(cs, CPU_INTERRUPT_HALT); cpc->vp_running &= ~i; } } -- 2.7.4
[Qemu-devel] [PATCH 0/3] mips: support configurable exception vector base
This series implements the last piece of the minimal support required to boot MIPSr6 SMP Linux on multiple Virtual Processors. Essentially it adds RESET_BASE register to CM GCR which can be used by the guest to specify the reset exception base address for each VP. It applies on top of GIC patches: https://lists.nongnu.org/archive/html/qemu-devel/2016-03/msg06223.html Thanks, Leon Leon Alrae (3): target-mips: add exception base to MIPS CPU hw/mips_cpc: make VP correctly start from the reset vector hw/mips_cmgcr: implement RESET_BASE register in CM GCR hw/misc/mips_cmgcr.c | 54 +++- hw/misc/mips_cpc.c | 5 ++-- include/hw/misc/mips_cmgcr.h | 18 +++ target-mips/cpu.h| 2 ++ target-mips/helper.c | 6 ++--- target-mips/translate.c | 9 +++- 6 files changed, 86 insertions(+), 8 deletions(-) -- 2.7.4
Re: [Qemu-devel] [PATCH v8 9/9] target-mips: Implement FCR31's R/W bitmask and related functionalities
> @@ -110,9 +110,11 @@ struct CPUMIPSFPUContext { > #define FCR0_PRID 8 > #define FCR0_REV 0 > /* fcsr */ > +uint32_t fcr31_rw_bitmask; > uint32_t fcr31; > -#define FCR31_ABS2008 19 > -#define FCR31_NAN2008 18 > +#define FCR31_NAN2008 18 > +#define FCR31_ABS2008 19 Now the order is inconsistent with other #defines in cpu.h, I think there's no need to touch these lines. > +#define FCR31_FS 24 > @@ -813,14 +815,21 @@ static inline void restore_rounding_mode(CPUMIPSState > *env) > > static inline void restore_flush_mode(CPUMIPSState *env) > { > -set_flush_to_zero((env->active_fpu.fcr31 & (1 << 24)) != 0, > +set_flush_to_zero((env->active_fpu.fcr31 & (1 << FCR31_FS)) != 0, it would be ideal to move this change with FCR31_FS to a separate patch as this isn't directly related to implementing fcr31_rw_bitmask. >&env->active_fpu.fp_status); > } > > +static inline void restore_snan_bit_mode(CPUMIPSState *env) > +{ > +set_snan_bit_is_one(((env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) == > 0), outermost parentheses can be removed > set_float_exception_flags(0, &env->active_fpu.fp_status); > -if ((GET_FP_ENABLE(env->active_fpu.fcr31) | 0x20) & > GET_FP_CAUSE(env->active_fpu.fcr31)) > +if ((GET_FP_ENABLE(env->active_fpu.fcr31) | 0x20) & > + GET_FP_CAUSE(env->active_fpu.fcr31)) { > do_raise_exception(env, EXCP_FPE, GETPC()); > +} Unrelated cosmetic change, pelase remove it from this patch. > @@ -465,6 +473,7 @@ static const mips_def_t mips_defs[] = > (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) | > (1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV), > .CP1_fcr31 = (1 << FCR31_ABS2008) | (1 << FCR31_NAN2008), > +.CP1_fcr31_rw_bitmask = 0xFF83, > .SEGBITS = 32, > .PABITS = 32, > .insn_flags = CPU_MIPS32R6 | ASE_MICROMIPS, > @@ -686,6 +705,7 @@ static const mips_def_t mips_defs[] = > (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) | > (1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV), > .CP1_fcr31 = (1 << FCR31_ABS2008) | (1 << FCR31_NAN2008), > +.CP1_fcr31_rw_bitmask = 0xFF83, > .SEGBITS = 48, > .PABITS = 48, > .insn_flags = CPU_MIPS64R6 | ASE_MSA, In MIPS R6 the floating point condition codes have been removed, consequently bits 31:25 and 23 became read-only 0. The fcr31_rw_bitmask for mips32r6-generic and mips64r6-generic cores should be 0x0103. Otherwise the patch looks good to me. Thanks, Leon
Re: [Qemu-devel] [PATCH v8 6/9] target-mips: Activate IEEE 754-2008 signaling NaN bit meaning for MSA
On Fri, Jun 03, 2016 at 08:43:12PM +0200, Aleksandar Markovic wrote: > From: Aleksandar Markovic > > Function msa_reset() is updated so that flag snan_bit_is_one is > properly set to 0. > > By applying this patch, a number of incorrect MSA behaviors that > require IEEE 754-2008 compliance will be fixed. Those are behaviors > that (up to the moment of applying this patch) did not get the desired > functionality from SoftFloat library with respect to distinguishing > between quiet and signaling NaN, getting default NaN values (both > quiet and signaling), establishing if a floating point number is NaN > or not, etc. > > Two examples: > > * FMAX, FMIN will now correctly detect and propagate NaNs. > * FCLASS.D ans FCLASS.S will now correcty detect NaN flavors. > > Signed-off-by: Aleksandar Markovic > --- > target-mips/translate_init.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) Reviewed-by: Leon Alrae
Re: [Qemu-devel] [PATCH v8 5/9] linux-user: Update preprocessor constants for Mips-specific e_flags bits
On Fri, Jun 03, 2016 at 08:43:11PM +0200, Aleksandar Markovic wrote: > From: Aleksandar Markovic > > Missing values EF_MIPS_FP64 and EF_MIPS_NAN2008 added, and the format > of the surrounding code segment adjusted. Please don't include whitespace fixes of other lines into the same patch: http://wiki.qemu.org/Contribute/SubmitAPatch#Don.27t_include_irrelevant_changes If you drop the adjustment of surrounding code then feel free to add: Reviewed-by: Leon Alrae Thanks, Leon > > Signed-off-by: Thomas Schwinge > Signed-off-by: Maciej W. Rozycki > Signed-off-by: Aleksandar Markovic > --- > include/elf.h | 18 ++ > 1 file changed, 10 insertions(+), 8 deletions(-) > > diff --git a/include/elf.h b/include/elf.h > index 28d448b..b7f59e4 100644 > --- a/include/elf.h > +++ b/include/elf.h > @@ -46,14 +46,16 @@ typedef int64_t Elf64_Sxword; > #define EF_MIPS_ABI_O32 0x1000 /* O32 ABI. */ > #define EF_MIPS_ABI_O64 0x2000 /* O32 extended for 64 > bit. */ > > -#define EF_MIPS_NOREORDER 0x0001 > -#define EF_MIPS_PIC 0x0002 > -#define EF_MIPS_CPIC 0x0004 > -#define EF_MIPS_ABI2 0x0020 > -#define EF_MIPS_OPTIONS_FIRST0x0080 > -#define EF_MIPS_32BITMODE0x0100 > -#define EF_MIPS_ABI 0xf000 > -#define EF_MIPS_ARCH 0xf000 > +#define EF_MIPS_NOREORDER 0x0001 > +#define EF_MIPS_PIC 0x0002 > +#define EF_MIPS_CPIC0x0004 > +#define EF_MIPS_ABI20x0020 > +#define EF_MIPS_OPTIONS_FIRST 0x0080 > +#define EF_MIPS_32BITMODE 0x0100 > +#define EF_MIPS_FP640x0200 > +#define EF_MIPS_NAN2008 0x0400 > +#define EF_MIPS_ABI 0xf000 > +#define EF_MIPS_ARCH0xf000 > > /* These constants define the different elf file types */ > #define ET_NONE 0
Re: [Qemu-devel] [PATCH v6 6/9] target-mips: Activate IEEE 754-2008 signaling NaN bit meaning
> diff --git a/target-mips/translate.c b/target-mips/translate.c > index e934884..2cdd2bd 100644 > --- a/target-mips/translate.c > +++ b/target-mips/translate.c > @@ -20129,7 +20129,11 @@ void cpu_state_reset(CPUMIPSState *env) > env->CP0_PageGrain = env->cpu_model->CP0_PageGrain; > env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0; > env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31; > -set_snan_bit_is_one(1, &env->active_fpu.fp_status); > +if ((env->active_fpu.fcr31 >> FCR31_NAN2008) & 1) { > +set_snan_bit_is_one(0, &env->active_fpu.fp_status); > +} else { > +set_snan_bit_is_one(1, &env->active_fpu.fp_status); > +} This change is reverted in patch #9, perhaps it will be better to fold it into that patch? Thanks, Leon > env->msair = env->cpu_model->MSAIR; > env->insn_flags = env->cpu_model->insn_flags; > > diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c > index e81a831..a37d8bb 100644 > --- a/target-mips/translate_init.c > +++ b/target-mips/translate_init.c > @@ -893,5 +893,6 @@ static void msa_reset(CPUMIPSState *env) > /* clear float_status nan mode */ > set_default_nan_mode(0, &env->active_tc.msa_fp_status); > > -set_snan_bit_is_one(1, &env->active_tc.msa_fp_status); > +/* set proper signanling bit meaning ("1" means "quiet") */ > +set_snan_bit_is_one(0, &env->active_tc.msa_fp_status); > } > -- > 1.9.1 >
Re: [Qemu-devel] [PATCH v6 9/9] target-mips: Implement FCR31's R/W bitmask and related functionalities
> - Add preprocessor constants for all bits of FCR31 and related masks > for its subfields. Introducing all these constants for fcr31_rw_bitmask doesn't seem necessary or useful > > - Modify handling of CFC1 and CTC1 instructions (cases 25, 26, 28) > so that they utilize newly-defind constants. This is just a cosmetic > change, to make the code more readable, and to avoid usage of > hardcoded constants. this an unrelated change; it should be moved to a separate patch > +static inline void restore_snan_bit_mode(CPUMIPSState *env) > +{ > +set_snan_bit_is_one(!((env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) != > 0), this is just: (env->active_fpu.fcr31 & (1 << FCR31_NAN2008)) == 0 > @@ -89,11 +89,9 @@ int mips_cpu_gdb_write_register(CPUState *cs, uint8_t > *mem_buf, int n) > if (env->CP0_Config1 & (1 << CP0C1_FP) && n >= 38 && n < 72) { > switch (n) { > case 70: > -env->active_fpu.fcr31 = tmp & 0xFF83; > -/* set rounding mode */ > -restore_rounding_mode(env); > -/* set flush-to-zero mode */ > -restore_flush_mode(env); > +env->active_fpu.fcr31 = (tmp & env->active_fpu.fcr31_rw_bitmask) > | > + (env->active_fpu.fcr31 & !(env->active_fpu.fcr31_rw_bitmask)); I think you wanted bitwise-not here > +restore_fp_status(env); > break; > case 71: > /* FIR is read-only. Ignore writes. */ > diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c > index 0d1e959..cb890bc 100644 > --- a/target-mips/op_helper.c > +++ b/target-mips/op_helper.c > @@ -2490,15 +2490,23 @@ target_ulong helper_cfc1(CPUMIPSState *env, uint32_t > reg) > } > break; > case 25: > -arg1 = ((env->active_fpu.fcr31 >> 24) & 0xfe) | > ((env->active_fpu.fcr31 >> 23) & 0x1); > +/* read from Floating Point Condition Codes Register (FCCR) */ > +arg1 = ((env->active_fpu.fcr31 >> 24) & 0xfe) | > + ((env->active_fpu.fcr31 >> 23) & 0x1); this is an unrelated cosmetic change, please remove it from this patch (there are more changes like that in this patch) > @@ -2558,42 +2566,66 @@ void helper_ctc1(CPUMIPSState *env, target_ulong > arg1, uint32_t fs, uint32_t rt) > } > break; > case 25: > +/* write to Floating Point Condition Codes Register (FCCR) */ > if ((env->insn_flags & ISA_MIPS32R6) || (arg1 & 0xff00)) { > return; > } > -env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0x017f) | > ((arg1 & 0xfe) << 24) | > - ((arg1 & 0x1) << 23); > +env->active_fpu.fcr31 = > +(env->active_fpu.fcr31 & FCR31_ROUNDING_MODE_MASK) | > +(env->active_fpu.fcr31 & FCR31_FLAGS_MASK) | > +(env->active_fpu.fcr31 & FCR31_ENABLE_MASK) | > +(env->active_fpu.fcr31 & FCR31_CAUSE_MASK) | > +(env->active_fpu.fcr31 & FCR31_IEEE2008_MASK) | > +(env->active_fpu.fcr31 & FCR31_IMPL_MASK) | > +(env->active_fpu.fcr31 & FCR31_FCC_MASK) | > +((arg1 & 0x1) << 23) | > +(env->active_fpu.fcr31 & FCR31_FS_MASK) | > +((arg1 & 0xfe) << 24); > break; I don't find it easier to read. CTC1 and CFC1 helpers became a mixture of various sub-masks and hardcoded constants. Also, it is now harder to map the implementation to the lines from CTC1/CFC1 in the MIPS64BIS manual: elseif fs = 25 then /* FCCR */ if temp31..8 != then UNPREDICTABLE else FCSR <- temp7..1 || FCSR24 || temp0 || FCSR22..0 Thanks, Leon
Re: [Qemu-devel] [PATCH v6 8/9] target-mips: Add nan2008 flavor of ..
On Mon, May 16, 2016 at 04:12:44PM +0200, Aleksandar Markovic wrote: > From: Aleksandar Markovic > > New set of helpers for handling nan2008-syle versions of instructions > .., for Mips R6. > > All involved instructions have float operand and integer result. Their > core functionality is implemented via invocations of appropriate SoftFloat > functions. The problematic cases are when the operand is a NaN, and also > when the operand (float) is out of the range of the result. > > Here one can distinguish three cases: > > CASE MIPS-A: (FCR31.NAN2008 == 1) > >1. Operand is a NaN, result should be 0; >2. Operand is larger than INT_MAX, result should be INT_MAX; >2. Operand is smaller than INT_MIN, result should be INT_MIN. > > CASE MIPS-B: (FCR31.NAN2008 == 0) > >1. Operand is a NaN, result should be INT_MAX; >2. Operand is larger than INT_MAX, result should be INT_MAX; >2. Operand is smaller than INT_MIN, result should be INT_MAX. > > CASE SOFTFLOAT: > >1. Operand is a NaN, result is INT_MAX; >2. Operand is larger than INT_MAX, result is INT_MAX; >2. Operand is smaller than INT_MIN, result is INT_MIN. > > It is interesting that neither MIPS-A nor MIPS-B desired behaviors > are in this sense identical to correspondent SoftFloat behavior. > > Current implementation of .. > implements case MIPS-B. This patch relates to case MIPS-A. For case > MIPS-A, only return value for NaN-operands should be corrected after > appropriate SoftFloat library function is called. > > Related MSA instructions FTRUNC_S and FTINT_S already handle well > all cases, in the fashion similar to the code from this patch. > > Signed-off-by: Aleksandar Markovic > --- > target-mips/helper.h| 18 +-- > target-mips/op_helper.c | 369 > +++++--- > target-mips/translate.c | 122 +--- > 3 files changed, 461 insertions(+), 48 deletions(-) Reviewed-by: Leon Alrae
[Qemu-devel] [PULL 1/2] target-mips: fix call to memset in soft reset code
From: Aurelien Jarno Recent versions of GCC report the following error when compiling target-mips/helper.c: qemu/target-mips/helper.c:542:9: warning: ‘memset’ used with length equal to number of elements without multiplication by element size [-Wmemset-elt-size] This is indeed correct and due to a wrong usage of sizeof(). Fix that. Cc: Stefan Weil Cc: Leon Alrae Cc: qemu-sta...@nongnu.org LP: https://bugs.launchpad.net/qemu/+bug/1577841 Signed-off-by: Aurelien Jarno Reviewed-by: Stefan Weil Reviewed-by: Leon Alrae Signed-off-by: Leon Alrae --- target-mips/helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target-mips/helper.c b/target-mips/helper.c index 1004ede..cfea177 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -539,7 +539,7 @@ void mips_cpu_do_interrupt(CPUState *cs) break; case EXCP_SRESET: env->CP0_Status |= (1 << CP0St_SR); -memset(env->CP0_WatchLo, 0, sizeof(*env->CP0_WatchLo)); +memset(env->CP0_WatchLo, 0, sizeof(env->CP0_WatchLo)); goto set_error_EPC; case EXCP_NMI: env->CP0_Status |= (1 << CP0St_NMI); -- 2.7.4
[Qemu-devel] [PULL 2/2] hw/display: QOM'ify jazz_led.c
From: "xiaoqiang.zhao" * Drop the old SysBus init function and use instance_init * Move graphic_console_init into realize stage Signed-off-by: xiaoqiang zhao Reviewed-by: Peter Maydell Signed-off-by: Leon Alrae --- hw/display/jazz_led.c | 18 +++--- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/hw/display/jazz_led.c b/hw/display/jazz_led.c index 09dcdb4..b72fdb1 100644 --- a/hw/display/jazz_led.c +++ b/hw/display/jazz_led.c @@ -267,16 +267,20 @@ static const GraphicHwOps jazz_led_ops = { .text_update = jazz_led_text_update, }; -static int jazz_led_init(SysBusDevice *dev) +static void jazz_led_init(Object *obj) { -LedState *s = JAZZ_LED(dev); +LedState *s = JAZZ_LED(obj); +SysBusDevice *dev = SYS_BUS_DEVICE(obj); -memory_region_init_io(&s->iomem, OBJECT(s), &led_ops, s, "led", 1); +memory_region_init_io(&s->iomem, obj, &led_ops, s, "led", 1); sysbus_init_mmio(dev, &s->iomem); +} -s->con = graphic_console_init(DEVICE(dev), 0, &jazz_led_ops, s); +static void jazz_led_realize(DeviceState *dev, Error **errp) +{ +LedState *s = JAZZ_LED(dev); -return 0; +s->con = graphic_console_init(dev, 0, &jazz_led_ops, s); } static void jazz_led_reset(DeviceState *d) @@ -291,18 +295,18 @@ static void jazz_led_reset(DeviceState *d) static void jazz_led_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); -SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); -k->init = jazz_led_init; dc->desc = "Jazz LED display", dc->vmsd = &vmstate_jazz_led; dc->reset = jazz_led_reset; +dc->realize = jazz_led_realize; } static const TypeInfo jazz_led_info = { .name = TYPE_JAZZ_LED, .parent= TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(LedState), +.instance_init = jazz_led_init, .class_init= jazz_led_class_init, }; -- 2.7.4
[Qemu-devel] [PULL 0/2] target-mips queue
Hi, Just two patches in the first target-mips pullreq for 2.7. Thanks, Leon Cc: Peter Maydell Cc: Aurelien Jarno The following changes since commit bfc766d38e1fae5767d43845c15c79ac8fa6d6af: Update version for v2.6.0 release (2016-05-11 16:44:26 +0100) are available in the git repository at: git://github.com/lalrae/qemu.git tags/mips-20160513 for you to fetch changes up to 7fe91a5b33fe100bbc68ee434f947752c69b3f68: hw/display: QOM'ify jazz_led.c (2016-05-13 09:33:38 +0100) MIPS patches 2016-05-13 Changes: * fix zeroing CP0.WatchLo registers in soft reset * QOMify Jazz led Aurelien Jarno (1): target-mips: fix call to memset in soft reset code xiaoqiang.zhao (1): hw/display: QOM'ify jazz_led.c hw/display/jazz_led.c | 18 +++--- target-mips/helper.c | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-)
Re: [Qemu-devel] [Qemu-arm] [PATCH RESEND 2/5] hw/display: QOM'ify jazz_led.c
On Thu, May 05, 2016 at 01:46:13PM +0100, Peter Maydell wrote: > On 5 May 2016 at 04:04, xiaoqiang zhao wrote: > > * Drop the old SysBus init function and use instance_init > > * Move graphic_console_init into realize stage > > > > Signed-off-by: xiaoqiang zhao > > --- > > hw/display/jazz_led.c | 18 +++--- > > 1 file changed, 11 insertions(+), 7 deletions(-) > > Reviewed-by: Peter Maydell > > CCing the MIPS maintainers and the listed maintainer for this > board so they can pick this patch up. Since there're no changes in v2 I applied this one (with Peter's rev-by) to target-mips queue. Thanks, Leon
Re: [Qemu-devel] [PATCH] target-mips: fix call to memset in soft reset code
On Mon, May 09, 2016 at 06:44:00PM +0200, Aurelien Jarno wrote: > Recent versions of GCC report the following error when compiling > target-mips/helper.c: > > qemu/target-mips/helper.c:542:9: warning: ‘memset’ used with length > equal to number of elements without multiplication by element size > [-Wmemset-elt-size] > > This is indeed correct and due to a wrong usage of sizeof(). Fix that. > > Cc: Stefan Weil > Cc: Leon Alrae > LP: https://bugs.launchpad.net/qemu/+bug/1577841 > Signed-off-by: Aurelien Jarno > --- > target-mips/helper.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) Applied to target-mips queue and added Cc: qemu-sta...@nongnu.org. Thanks, Leon