[Qemu-devel] [PATCH] hw/mips_cpc: kick a VP when putting it into Run state

2016-09-27 Thread Leon Alrae
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

2016-09-27 Thread Leon Alrae
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

2016-09-26 Thread Leon Alrae
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

2016-09-26 Thread Leon Alrae
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

2016-09-26 Thread Leon Alrae
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

2016-09-23 Thread Leon Alrae
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

2016-09-23 Thread Leon Alrae
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

2016-09-23 Thread Leon Alrae
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

2016-09-23 Thread Leon Alrae
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

2016-09-23 Thread Leon Alrae
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

2016-09-23 Thread Leon Alrae
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

2016-09-23 Thread Leon Alrae
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

2016-09-23 Thread Leon Alrae
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

2016-09-23 Thread Leon Alrae
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

2016-09-23 Thread Leon Alrae
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

2016-09-22 Thread Leon Alrae
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

2016-09-21 Thread Leon Alrae
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

2016-09-21 Thread Leon Alrae
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

2016-09-21 Thread Leon Alrae
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

2016-09-21 Thread Leon Alrae
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

2016-09-21 Thread Leon Alrae
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

2016-09-21 Thread Leon Alrae
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

2016-09-19 Thread Leon Alrae
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

2016-09-15 Thread Leon Alrae
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

2016-09-15 Thread Leon Alrae
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

2016-09-15 Thread Leon Alrae
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

2016-09-15 Thread Leon Alrae
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

2016-09-13 Thread Leon Alrae
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

2016-09-12 Thread Leon Alrae
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

2016-09-09 Thread Leon Alrae
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

2016-09-09 Thread Leon Alrae
> +#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

2016-09-09 Thread Leon Alrae
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

2016-09-09 Thread Leon Alrae
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

2016-09-08 Thread Leon Alrae
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

2016-09-08 Thread Leon Alrae
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

2016-09-08 Thread Leon Alrae
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

2016-09-08 Thread Leon Alrae
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

2016-09-08 Thread Leon Alrae
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

2016-09-07 Thread Leon Alrae
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

2016-09-07 Thread Leon Alrae
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

2016-09-07 Thread Leon Alrae
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

2016-09-07 Thread Leon Alrae
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

2016-07-29 Thread Leon Alrae
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

2016-07-29 Thread Leon Alrae
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

2016-07-29 Thread Leon Alrae
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

2016-07-28 Thread Leon Alrae
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

2016-07-26 Thread Leon Alrae
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

2016-07-26 Thread Leon Alrae
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

2016-07-26 Thread Leon Alrae
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

2016-07-15 Thread Leon Alrae
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

2016-07-12 Thread Leon Alrae
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

2016-07-12 Thread Leon Alrae
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

2016-07-12 Thread Leon Alrae
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

2016-07-12 Thread Leon Alrae
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

2016-07-12 Thread Leon Alrae
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

2016-07-12 Thread Leon Alrae
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

2016-07-12 Thread Leon Alrae
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

2016-07-12 Thread Leon Alrae
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

2016-07-12 Thread Leon Alrae
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

2016-07-12 Thread Leon Alrae
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

2016-07-12 Thread Leon Alrae
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

2016-07-12 Thread Leon Alrae
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

2016-07-11 Thread Leon Alrae
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

2016-06-27 Thread Leon Alrae
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

2016-06-27 Thread Leon Alrae
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

2016-06-27 Thread Leon Alrae
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

2016-06-27 Thread Leon Alrae
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

2016-06-27 Thread Leon Alrae
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

2016-06-27 Thread Leon Alrae
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

2016-06-26 Thread Leon Alrae
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 .

2016-06-26 Thread Leon Alrae
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

2016-06-26 Thread Leon Alrae
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

2016-06-26 Thread Leon Alrae
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()

2016-06-26 Thread Leon Alrae
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

2016-06-26 Thread Leon Alrae
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 ..

2016-06-26 Thread Leon Alrae
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

2016-06-26 Thread Leon Alrae
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

2016-06-26 Thread Leon Alrae
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

2016-06-26 Thread Leon Alrae
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

2016-06-26 Thread Leon Alrae
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

2016-06-23 Thread Leon Alrae
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 ..

2016-06-14 Thread Leon Alrae
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

2016-06-14 Thread Leon Alrae
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

2016-06-14 Thread Leon Alrae
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

2016-06-14 Thread Leon Alrae
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

2016-06-09 Thread Leon Alrae
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

2016-06-09 Thread Leon Alrae
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

2016-06-09 Thread Leon Alrae
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

2016-06-09 Thread Leon Alrae
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

2016-06-06 Thread Leon Alrae
> @@ -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

2016-06-06 Thread Leon Alrae
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

2016-06-06 Thread Leon Alrae
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

2016-06-02 Thread Leon Alrae
> 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

2016-06-02 Thread Leon Alrae
> - 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 ..

2016-05-31 Thread Leon Alrae
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

2016-05-13 Thread Leon Alrae
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

2016-05-13 Thread Leon Alrae
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

2016-05-13 Thread Leon Alrae
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

2016-05-13 Thread Leon Alrae
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

2016-05-12 Thread Leon Alrae
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




  1   2   3   4   5   6   7   8   9   10   >