All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/14] target/mips: Add Enhanced Virtual Addressing (EVA) support
@ 2017-07-18 11:55 James Hogan
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 1/14] target/mips: Fix MIPS64 MFC0 UserLocal on BE host James Hogan
                   ` (14 more replies)
  0 siblings, 15 replies; 30+ messages in thread
From: James Hogan @ 2017-07-18 11:55 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: qemu-devel, James Hogan, Aurelien Jarno, Petar Jovanovic

This patchset implements MIPS Enhanced Virtual Addressing (EVA) support
in QEMU.

The patches are grouped as follows:

 - Patches 1-3: Preliminary fixes.
   A few fixes are made for issues spotted during development.

 - Patch 4: CP0_EBase.WG (write gate).
   This allows more bits of CP0_EBase to be written, which allows the
   exception vector to be moved into a different segment than
   kseg0/kseg1. The related CP0_Config5.CV allows cache error exceptions
   not to be forced to get handled by KSeg1.

 - Patches 5-8: EVA user memory access instructions (CP0_Config5.EVA).
   These allow kernel code to access the user mode view of memory, which
   can no longer be done reliably with normal memory access instructions
   for MUSUK segment access mode (see below).

 - Patches 9-12: Segmentation control (CP0_Config3.SC).
   New cop0 registers are added to reconfigure the virtual memory
   segments. This allows the traditionally fixed virtual memory segments
   to be rearranged, and also allows segments to appear differently
   based on execution mode, for example the access mode MUSUK (Mapped
   User Supervisor, Unmapped Kernel) makes a segment TLB mapped to user
   mode and cached unmapped (direct window to physical) to kernel mode,
   and if EU=1 it is also uncached unmapped to error level (which
   requires the addition of a new MMU mode).

 - Patch 13: P5600 EVA support.
   We add the required capabilities to the P5600 CPU type to allow a
   Malta EVA kernel to be executed.

 - Patch 14: I6400 & MIPS64R2-generic CP0_Ebase.WG support.
   We add WG bit support to these MIPS64 CPUs so the guest kernel can
   run KVM T&E.

Notable limitations:

 - Neither CACHEE (the new EVA instruction) or CACHE (the pre-existing
   non-EVA instruction) generate TLB exceptions for bad addresses, as
   QEMU implements them only with a Cop0 privilege check.

 - No attempt has been made to implement BEV overlays yet, which would
   allow non-standard boot exception vector addresses to be accessed in
   kernel mode, even if the underlying segment is changed. This should
   be done at some point, but wasn't necessary for my purposes.

 - MIPS64 segmentation control (for XKPhys) is functional, however there
   are still a few corner cases that need resolving:
    - EntryHi writability on r6 (you can't write an XKPhys address).
    - R6 style Status.KX,SX,UX writability (KX=0 => SX=0, and SX=0 =>
      UX=0).
    - R6 style addressing special cases & sign extension.
   so I wouldn't recommend enabling it for any CPUs yet. P6600 is the
   only real core that implements it anyway.

Changes in v2:

 - Rebased on 2.9.0
 - New patches 1-3, with some misc fixes
 - CP0_EBase.WG (patch 4):
    - Fix CP0_EBase.WG to be read only when WG is not set in
      CP0_EBase_rw_bitmask, otherwise it will be wrongly probed as
      present.
    - Make cache error exception vector conditional on Config3.SC as
      well as Config5.CV, as per the PRA, and take the CP0C3_SC
      definition from patch 7 (Yongbok).
    - Rename CP0_EBase_rw_bitmask to CP0_EBaseWG_rw_bitmask (Yongbok).
 - Decode EVA load & stores (patch 6)
    - Fix typo in commit message (Yongbok).
    - Use sextract32 (Yongbok).
 - New patch 7, to decode microMIPS EVA loads & stores (Yongbok).
 - Abstract mmu_idx from hflags (patch 9):
    - Also convert reference to hflags & MIPS_HFLAG_KSU in op_helper.c
      to cpu_mmu_index (Yongbok).
 - Add an MMU mode for ERL (patch 10):
    - Add ERL case to log output where cpu_mmu_index() is now used in
      op_helper.c
 - Add segmentation control registers (Patch 11):
    - Use ld_tl and ext32s_tl rather than ld32s_tl to avoid big endian
      host, MIPS64 target issues (Yongbok).
    - Add missing break in DMFC0 CP0_SegCtl2 case.
 - Implement segmentation control (Patch 12):
    - Use hwaddr instead of target_ulong for physical addresses in
      get_seg[ctl]_physical_address() (Yongbok).
    - Fix xkphys privilege control based on access mode (am) (Yongbok).
    - Fix xkphys TLB faults to use XTLB.
 - New patch 14.

Cc: Yongbok Kim <yongbok.kim@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
Cc: Petar Jovanovic <petar.jovanovic@imgtec.com>

James Hogan (14):
  target/mips: Fix MIPS64 MFC0 UserLocal on BE host
  target/mips: Fix TLBWI shadow flush for EHINV,XI,RI
  target/mips: Weaken TLB flush on UX,SX,KX,ASID changes
  target/mips: Add CP0_Ebase.WG (write gate) support
  target/mips: Prepare loads/stores for EVA
  target/mips: Decode MIPS32 EVA load & store instructions
  target/mips: Decode microMIPS EVA load & store instructions
  target/mips: Check memory permissions with mem_idx
  target/mips: Abstract mmu_idx from hflags
  target/mips: Add an MMU mode for ERL
  target/mips: Add segmentation control registers
  target/mips: Implement segmentation control
  target/mips: Add EVA support to P5600
  target/mips: Enable CP0_EBase.WG on MIPS64 CPUs

 target/mips/cpu.h            |  58 ++++-
 target/mips/helper.c         | 210 ++++++++++++++-----
 target/mips/helper.h         |   3 +-
 target/mips/machine.c        |   9 +-
 target/mips/op_helper.c      |  58 ++++-
 target/mips/translate.c      | 405 ++++++++++++++++++++++++++++++++----
 target/mips/translate_init.c |  17 +-
 7 files changed, 644 insertions(+), 116 deletions(-)

-- 
git-series 0.8.10

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 1/14] target/mips: Fix MIPS64 MFC0 UserLocal on BE host
  2017-07-18 11:55 [Qemu-devel] [PATCH 0/14] target/mips: Add Enhanced Virtual Addressing (EVA) support James Hogan
@ 2017-07-18 11:55 ` James Hogan
  2017-07-18 14:37   ` Yongbok Kim
  2017-07-19 10:27   ` Aurelien Jarno
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 2/14] target/mips: Fix TLBWI shadow flush for EHINV, XI, RI James Hogan
                   ` (13 subsequent siblings)
  14 siblings, 2 replies; 30+ messages in thread
From: James Hogan @ 2017-07-18 11:55 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: qemu-devel, James Hogan, Aurelien Jarno, Petar Jovanovic

Using MFC0 to read CP0_UserLocal uses tcg_gen_ld32s_tl, however
CP0_UserLocal is a target_ulong. On a big endian host with a MIPS64
target this reads and sign extends the more significant half of the
64-bit register.

Fix this by using ld_tl to load the whole target_ulong and ext32s_tl to
sign extend it, as done for various other target_ulong COP0 registers.

Fixes: d279279e2b5c ("target-mips: implement UserLocal Register")
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Yongbok Kim <yongbok.kim@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
Cc: Petar Jovanovic <petar.jovanovic@imgtec.com>
---
Changes in v2:
- New patch.
---
 target/mips/translate.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 3022f349cb2a..556aba969a12 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -5138,8 +5138,9 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
             goto cp0_unimplemented;
         case 2:
             CP0_CHECK(ctx->ulri);
-            tcg_gen_ld32s_tl(arg, cpu_env,
-                             offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
+            tcg_gen_ld_tl(arg, cpu_env,
+                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
+            tcg_gen_ext32s_tl(arg, arg);
             rn = "UserLocal";
             break;
         default:
-- 
git-series 0.8.10

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 2/14] target/mips: Fix TLBWI shadow flush for EHINV, XI, RI
  2017-07-18 11:55 [Qemu-devel] [PATCH 0/14] target/mips: Add Enhanced Virtual Addressing (EVA) support James Hogan
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 1/14] target/mips: Fix MIPS64 MFC0 UserLocal on BE host James Hogan
@ 2017-07-18 11:55 ` James Hogan
  2017-07-20 15:16   ` Yongbok Kim
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 3/14] target/mips: Weaken TLB flush on UX, SX, KX, ASID changes James Hogan
                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 30+ messages in thread
From: James Hogan @ 2017-07-18 11:55 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: qemu-devel, James Hogan, Aurelien Jarno

Writing specific TLB entries with TLBWI flushes shadow TLB entries
unless an existing entry is having its access permissions upgraded. This
is necessary as software would from then on expect the previous mapping
in that entry to no longer be in effect (even if QEMU has quietly
evicted it to the shadow TLB on a TLBWR).

However it won't do this if only EHINV, XI, or RI bits have been set,
even if that results in a reduction of permissions, so add the necessary
checks to invoke the flush when these bits are set.

Fixes: 2fb58b73746e ("target-mips: add RI and XI fields to TLB entry")
Fixes: 9456c2fbcd82 ("target-mips: add TLBINV support")
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Yongbok Kim <yongbok.kim@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
---
Changes in v2:
- New patch.
---
 target/mips/op_helper.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index e5f3ea40420e..1961cacfab18 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -2029,7 +2029,7 @@ void r4k_helper_tlbwi(CPUMIPSState *env)
     int idx;
     target_ulong VPN;
     uint16_t ASID;
-    bool G, V0, D0, V1, D1;
+    bool EHINV, G, V0, D0, V1, D1, XI0, XI1, RI0, RI1;
 
     idx = (env->CP0_Index & ~0x80000000) % env->tlb->nb_tlb;
     tlb = &env->tlb->mmu.r4k.tlb[idx];
@@ -2038,17 +2038,25 @@ void r4k_helper_tlbwi(CPUMIPSState *env)
     VPN &= env->SEGMask;
 #endif
     ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
+    EHINV = (env->CP0_EntryHi & (1 << CP0EnHi_EHINV)) != 0;
     G = env->CP0_EntryLo0 & env->CP0_EntryLo1 & 1;
     V0 = (env->CP0_EntryLo0 & 2) != 0;
     D0 = (env->CP0_EntryLo0 & 4) != 0;
+    XI0 = (env->CP0_EntryLo0 >> CP0EnLo_XI) & 1;
+    RI0 = (env->CP0_EntryLo0 >> CP0EnLo_RI) & 1;
     V1 = (env->CP0_EntryLo1 & 2) != 0;
     D1 = (env->CP0_EntryLo1 & 4) != 0;
+    XI1 = (env->CP0_EntryLo1 >> CP0EnLo_XI) & 1;
+    RI1 = (env->CP0_EntryLo1 >> CP0EnLo_RI) & 1;
 
     /* Discard cached TLB entries, unless tlbwi is just upgrading access
        permissions on the current entry. */
     if (tlb->VPN != VPN || tlb->ASID != ASID || tlb->G != G ||
+        (!tlb->EHINV && EHINV) ||
         (tlb->V0 && !V0) || (tlb->D0 && !D0) ||
-        (tlb->V1 && !V1) || (tlb->D1 && !D1)) {
+        (!tlb->XI0 && XI0) || (!tlb->RI0 && RI0) ||
+        (tlb->V1 && !V1) || (tlb->D1 && !D1) ||
+        (!tlb->XI1 && XI1) || (!tlb->RI1 && RI1)) {
         r4k_mips_tlb_flush_extra(env, env->tlb->nb_tlb);
     }
 
-- 
git-series 0.8.10

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 3/14] target/mips: Weaken TLB flush on UX, SX, KX, ASID changes
  2017-07-18 11:55 [Qemu-devel] [PATCH 0/14] target/mips: Add Enhanced Virtual Addressing (EVA) support James Hogan
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 1/14] target/mips: Fix MIPS64 MFC0 UserLocal on BE host James Hogan
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 2/14] target/mips: Fix TLBWI shadow flush for EHINV, XI, RI James Hogan
@ 2017-07-18 11:55 ` James Hogan
  2017-07-20 15:17   ` Yongbok Kim
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 4/14] target/mips: Add CP0_Ebase.WG (write gate) support James Hogan
                   ` (11 subsequent siblings)
  14 siblings, 1 reply; 30+ messages in thread
From: James Hogan @ 2017-07-18 11:55 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: qemu-devel, James Hogan, Aurelien Jarno

There is no need to invalidate any shadow TLB entries when the ASID
changes or when access to one of the 64-bit segments has been disabled,
since doing so doesn't reveal to software whether any TLB entries have
been evicted into the shadow half of the TLB.

Therefore weaken the tlb flushes in these cases to only flush the QEMU
TLB.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Yongbok Kim <yongbok.kim@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
---
Changes in v2:
- New patch.
---
 target/mips/helper.c    | 2 +-
 target/mips/op_helper.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/mips/helper.c b/target/mips/helper.c
index e359ca3b448d..ceaeb8ceaf49 100644
--- a/target/mips/helper.c
+++ b/target/mips/helper.c
@@ -290,7 +290,7 @@ void cpu_mips_store_status(CPUMIPSState *env, target_ulong val)
 #if defined(TARGET_MIPS64)
     if ((env->CP0_Status ^ old) & (old & (7 << CP0St_UX))) {
         /* Access to at least one of the 64-bit segments has been disabled */
-        cpu_mips_tlb_flush(env);
+        tlb_flush(CPU(mips_env_get_cpu(env)));
     }
 #endif
     if (env->CP0_Config3 & (1 << CP0C3_MT)) {
diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index 1961cacfab18..c07f68ce1a97 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -1416,7 +1416,7 @@ void helper_mtc0_entryhi(CPUMIPSState *env, target_ulong arg1)
     /* If the ASID changes, flush qemu's TLB.  */
     if ((old & env->CP0_EntryHi_ASID_mask) !=
         (val & env->CP0_EntryHi_ASID_mask)) {
-        cpu_mips_tlb_flush(env);
+        tlb_flush(CPU(mips_env_get_cpu(env)));
     }
 }
 
-- 
git-series 0.8.10

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 4/14] target/mips: Add CP0_Ebase.WG (write gate) support
  2017-07-18 11:55 [Qemu-devel] [PATCH 0/14] target/mips: Add Enhanced Virtual Addressing (EVA) support James Hogan
                   ` (2 preceding siblings ...)
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 3/14] target/mips: Weaken TLB flush on UX, SX, KX, ASID changes James Hogan
@ 2017-07-18 11:55 ` James Hogan
  2017-07-19 14:54   ` Yongbok Kim
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 5/14] target/mips: Prepare loads/stores for EVA James Hogan
                   ` (10 subsequent siblings)
  14 siblings, 1 reply; 30+ messages in thread
From: James Hogan @ 2017-07-18 11:55 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: qemu-devel, James Hogan, Aurelien Jarno

Add support for the CP0_EBase.WG bit, which allows upper bits to be
written (bits 31:30 on MIPS32, or bits 63:30 on MIPS64), along with the
CP0_Config5.CV bit to control whether the exception vector for Cache
Error exceptions is forced into KSeg1.

This is necessary on MIPS32 to support Segmentation Control and Enhanced
Virtual Addressing (EVA) extensions (where KSeg1 addresses may not
represent an unmapped uncached segment).

It is also useful on MIPS64 to allow the exception base to reside in
XKPhys, and possibly out of range of KSEG0 and KSEG1.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Yongbok Kim <yongbok.kim@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
---
Changes in v2:
- Fix CP0_EBase.WG to be read only when WG is not set in
  CP0_EBase_rw_bitmask, otherwise it will be wrongly probed as present.
- Make cache error exception vector conditional on Config3.SC as well as
  Config5.CV, as per the PRA, and take the CP0C3_SC definition from
  patch 7 (Yongbok).
- Rename CP0_EBase_rw_bitmask to CP0_EBaseWG_rw_bitmask (Yongbok).
---
 target/mips/cpu.h            |  5 ++++-
 target/mips/helper.c         | 14 ++++++++------
 target/mips/machine.c        |  6 +++---
 target/mips/op_helper.c      | 12 ++++++++++--
 target/mips/translate.c      |  8 +++++---
 target/mips/translate_init.c |  1 +
 6 files changed, 31 insertions(+), 15 deletions(-)

diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 4a4747af2545..2b699a0e2456 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -399,7 +399,9 @@ struct CPUMIPSState {
 #define CP0Ca_EC    2
     target_ulong CP0_EPC;
     int32_t CP0_PRid;
-    int32_t CP0_EBase;
+    target_ulong CP0_EBase;
+    target_ulong CP0_EBaseWG_rw_bitmask;
+#define CP0EBase_WG 11
     target_ulong CP0_CMGCRBase;
     int32_t CP0_Config0;
 #define CP0C0_M    31
@@ -447,6 +449,7 @@ struct CPUMIPSState {
 #define CP0C3_MSAP  28
 #define CP0C3_BP 27
 #define CP0C3_BI 26
+#define CP0C3_SC 25
 #define CP0C3_IPLW 21
 #define CP0C3_MMAR 18
 #define CP0C3_MCU  17
diff --git a/target/mips/helper.c b/target/mips/helper.c
index ceaeb8ceaf49..cd07995eedb2 100644
--- a/target/mips/helper.c
+++ b/target/mips/helper.c
@@ -829,11 +829,7 @@ void mips_cpu_do_interrupt(CPUState *cs)
         goto set_EPC;
     case EXCP_CACHE:
         cause = 30;
-        if (env->CP0_Status & (1 << CP0St_BEV)) {
-            offset = 0x100;
-        } else {
-            offset = 0x20000100;
-        }
+        offset = 0x100;
  set_EPC:
         if (!(env->CP0_Status & (1 << CP0St_EXL))) {
             env->CP0_EPC = exception_resume_pc(env);
@@ -859,9 +855,15 @@ void mips_cpu_do_interrupt(CPUState *cs)
         env->hflags &= ~MIPS_HFLAG_BMASK;
         if (env->CP0_Status & (1 << CP0St_BEV)) {
             env->active_tc.PC = env->exception_base + 0x200;
+        } else if (cause == 30 && !(env->CP0_Config3 & (1 << CP0C3_SC) &&
+                                    env->CP0_Config5 & (1 << CP0C5_CV))) {
+            /* Force KSeg1 for cache errors */
+            env->active_tc.PC = (int32_t)KSEG1_BASE |
+                                (env->CP0_EBase & 0x1FFFF000);
         } else {
-            env->active_tc.PC = (int32_t)(env->CP0_EBase & ~0x3ff);
+            env->active_tc.PC = env->CP0_EBase & ~0xfff;
         }
+
         env->active_tc.PC += offset;
         set_hflags_for_handler(env);
         env->CP0_Cause = (env->CP0_Cause & ~(0x1f << CP0Ca_EC)) | (cause << CP0Ca_EC);
diff --git a/target/mips/machine.c b/target/mips/machine.c
index 38c8fe932832..91e31a7c2fe8 100644
--- a/target/mips/machine.c
+++ b/target/mips/machine.c
@@ -211,8 +211,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 */
@@ -272,7 +272,7 @@ const VMStateDescription vmstate_mips_cpu = {
         VMSTATE_INT32(env.CP0_Cause, MIPSCPU),
         VMSTATE_UINTTL(env.CP0_EPC, MIPSCPU),
         VMSTATE_INT32(env.CP0_PRid, MIPSCPU),
-        VMSTATE_INT32(env.CP0_EBase, MIPSCPU),
+        VMSTATE_UINTTL(env.CP0_EBase, MIPSCPU),
         VMSTATE_INT32(env.CP0_Config0, MIPSCPU),
         VMSTATE_INT32(env.CP0_Config1, MIPSCPU),
         VMSTATE_INT32(env.CP0_Config2, MIPSCPU),
diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index c07f68ce1a97..ba8b159d3bac 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -1515,14 +1515,22 @@ target_ulong helper_mftc0_ebase(CPUMIPSState *env)
 
 void helper_mtc0_ebase(CPUMIPSState *env, target_ulong arg1)
 {
-    env->CP0_EBase = (env->CP0_EBase & ~0x3FFFF000) | (arg1 & 0x3FFFF000);
+    target_ulong mask = 0x3FFFF000 | env->CP0_EBaseWG_rw_bitmask;
+    if (arg1 & (1 << CP0EBase_WG) & mask) {
+        mask |= ~0x3FFFFFFF;
+    }
+    env->CP0_EBase = (env->CP0_EBase & ~mask) | (arg1 & mask);
 }
 
 void helper_mttc0_ebase(CPUMIPSState *env, target_ulong arg1)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
     CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
-    other->CP0_EBase = (other->CP0_EBase & ~0x3FFFF000) | (arg1 & 0x3FFFF000);
+    target_ulong mask = 0x3FFFF000 | env->CP0_EBaseWG_rw_bitmask;
+    if (arg1 & (1 << CP0EBase_WG) & mask) {
+        mask |= ~0x3FFFFFFF;
+    }
+    other->CP0_EBase = (other->CP0_EBase & ~mask) | (arg1 & mask);
 }
 
 target_ulong helper_mftc0_configx(CPUMIPSState *env, target_ulong idx)
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 556aba969a12..c9afcfe3f537 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -5326,7 +5326,8 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
             break;
         case 1:
             check_insn(ctx, ISA_MIPS32R2);
-            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
+            tcg_gen_ext32s_tl(arg, arg);
             rn = "EBase";
             break;
         case 3:
@@ -6637,7 +6638,7 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
             break;
         case 1:
             check_insn(ctx, ISA_MIPS32R2);
-            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
             rn = "EBase";
             break;
         case 3:
@@ -20292,6 +20293,7 @@ void cpu_state_reset(CPUMIPSState *env)
     env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
     env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
     env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
+    env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
     env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
     env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
     env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
@@ -20342,7 +20344,7 @@ void cpu_state_reset(CPUMIPSState *env)
     if (kvm_enabled()) {
         env->CP0_EBase |= 0x40000000;
     } else {
-        env->CP0_EBase |= 0x80000000;
+        env->CP0_EBase |= (int32_t)0x80000000;
     }
     if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
         env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
diff --git a/target/mips/translate_init.c b/target/mips/translate_init.c
index 6ae23e476f79..8f8196ed5a6d 100644
--- a/target/mips/translate_init.c
+++ b/target/mips/translate_init.c
@@ -101,6 +101,7 @@ struct mips_def_t {
     int32_t CP0_SRSConf4;
     int32_t CP0_PageGrain_rw_bitmask;
     int32_t CP0_PageGrain;
+    target_ulong CP0_EBaseWG_rw_bitmask;
     int insn_flags;
     enum mips_mmu_types mmu_type;
 };
-- 
git-series 0.8.10

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 5/14] target/mips: Prepare loads/stores for EVA
  2017-07-18 11:55 [Qemu-devel] [PATCH 0/14] target/mips: Add Enhanced Virtual Addressing (EVA) support James Hogan
                   ` (3 preceding siblings ...)
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 4/14] target/mips: Add CP0_Ebase.WG (write gate) support James Hogan
@ 2017-07-18 11:55 ` James Hogan
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 6/14] target/mips: Decode MIPS32 EVA load & store instructions James Hogan
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 30+ messages in thread
From: James Hogan @ 2017-07-18 11:55 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: qemu-devel, James Hogan, Aurelien Jarno

EVA load and store instructions access the user mode address map, so
they need to use mem_idx of MIPS_HFLAG_UM. Update the various utility
functions to allow mem_idx to be more easily overridden from the
decoding logic.

Specifically we add a mem_idx argument to the op_ld/st_* helpers used
for atomics, and a mem_idx local variable to gen_ld(), gen_st(), and
gen_st_cond().

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Reviewed-by: Yongbok Kim <yongbok.kim@imgtec.com>
Cc: Yongbok Kim <yongbok.kim@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
---
 target/mips/translate.c | 77 ++++++++++++++++++++++--------------------
 1 file changed, 42 insertions(+), 35 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index c9afcfe3f537..428f71795a5c 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -2029,7 +2029,8 @@ FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
 /* load/store instructions. */
 #ifdef CONFIG_USER_ONLY
 #define OP_LD_ATOMIC(insn,fname)                                           \
-static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
+static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
+                                DisasContext *ctx)                         \
 {                                                                          \
     TCGv t0 = tcg_temp_new();                                              \
     tcg_gen_mov_tl(t0, arg1);                                              \
@@ -2040,9 +2041,10 @@ static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
 }
 #else
 #define OP_LD_ATOMIC(insn,fname)                                           \
-static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
+static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
+                                DisasContext *ctx)                         \
 {                                                                          \
-    gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx);                        \
+    gen_helper_1e1i(insn, ret, arg1, mem_idx);                             \
 }
 #endif
 OP_LD_ATOMIC(ll,ld32s);
@@ -2053,7 +2055,8 @@ OP_LD_ATOMIC(lld,ld64);
 
 #ifdef CONFIG_USER_ONLY
 #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
-static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
+static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx,   \
+                                DisasContext *ctx)                           \
 {                                                                            \
     TCGv t0 = tcg_temp_new();                                                \
     TCGLabel *l1 = gen_new_label();                                          \
@@ -2077,10 +2080,11 @@ static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx)
 }
 #else
 #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
-static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
+static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx,   \
+                                DisasContext *ctx)                           \
 {                                                                            \
     TCGv t0 = tcg_temp_new();                                                \
-    gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx);                     \
+    gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx);                          \
     gen_store_gpr(t0, rt);                                                   \
     tcg_temp_free(t0);                                                       \
 }
@@ -2123,6 +2127,7 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
                    int rt, int base, int16_t offset)
 {
     TCGv t0, t1, t2;
+    int mem_idx = ctx->mem_idx;
 
     if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
         /* Loongson CPU uses a load to zero register for prefetch.
@@ -2137,32 +2142,32 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
     switch (opc) {
 #if defined(TARGET_MIPS64)
     case OPC_LWU:
-        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL |
+        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
                            ctx->default_tcg_memop_mask);
         gen_store_gpr(t0, rt);
         break;
     case OPC_LD:
-        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
+        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
                            ctx->default_tcg_memop_mask);
         gen_store_gpr(t0, rt);
         break;
     case OPC_LLD:
     case R6_OPC_LLD:
-        op_ld_lld(t0, t0, ctx);
+        op_ld_lld(t0, t0, mem_idx, ctx);
         gen_store_gpr(t0, rt);
         break;
     case OPC_LDL:
         t1 = tcg_temp_new();
         /* Do a byte access to possibly trigger a page
            fault with the unaligned address.  */
-        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
         tcg_gen_andi_tl(t1, t0, 7);
 #ifndef TARGET_WORDS_BIGENDIAN
         tcg_gen_xori_tl(t1, t1, 7);
 #endif
         tcg_gen_shli_tl(t1, t1, 3);
         tcg_gen_andi_tl(t0, t0, ~7);
-        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
+        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
         tcg_gen_shl_tl(t0, t0, t1);
         t2 = tcg_const_tl(-1);
         tcg_gen_shl_tl(t2, t2, t1);
@@ -2177,14 +2182,14 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
         t1 = tcg_temp_new();
         /* Do a byte access to possibly trigger a page
            fault with the unaligned address.  */
-        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
         tcg_gen_andi_tl(t1, t0, 7);
 #ifdef TARGET_WORDS_BIGENDIAN
         tcg_gen_xori_tl(t1, t1, 7);
 #endif
         tcg_gen_shli_tl(t1, t1, 3);
         tcg_gen_andi_tl(t0, t0, ~7);
-        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
+        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
         tcg_gen_shr_tl(t0, t0, t1);
         tcg_gen_xori_tl(t1, t1, 63);
         t2 = tcg_const_tl(0xfffffffffffffffeull);
@@ -2200,7 +2205,7 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
         t1 = tcg_const_tl(pc_relative_pc(ctx));
         gen_op_addr_add(ctx, t0, t0, t1);
         tcg_temp_free(t1);
-        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
+        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
         gen_store_gpr(t0, rt);
         break;
 #endif
@@ -2208,44 +2213,44 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
         t1 = tcg_const_tl(pc_relative_pc(ctx));
         gen_op_addr_add(ctx, t0, t0, t1);
         tcg_temp_free(t1);
-        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
+        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
         gen_store_gpr(t0, rt);
         break;
     case OPC_LW:
-        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
+        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
                            ctx->default_tcg_memop_mask);
         gen_store_gpr(t0, rt);
         break;
     case OPC_LH:
-        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
+        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
                            ctx->default_tcg_memop_mask);
         gen_store_gpr(t0, rt);
         break;
     case OPC_LHU:
-        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW |
+        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
                            ctx->default_tcg_memop_mask);
         gen_store_gpr(t0, rt);
         break;
     case OPC_LB:
-        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
+        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
         gen_store_gpr(t0, rt);
         break;
     case OPC_LBU:
-        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
+        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
         gen_store_gpr(t0, rt);
         break;
     case OPC_LWL:
         t1 = tcg_temp_new();
         /* Do a byte access to possibly trigger a page
            fault with the unaligned address.  */
-        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
         tcg_gen_andi_tl(t1, t0, 3);
 #ifndef TARGET_WORDS_BIGENDIAN
         tcg_gen_xori_tl(t1, t1, 3);
 #endif
         tcg_gen_shli_tl(t1, t1, 3);
         tcg_gen_andi_tl(t0, t0, ~3);
-        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
+        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
         tcg_gen_shl_tl(t0, t0, t1);
         t2 = tcg_const_tl(-1);
         tcg_gen_shl_tl(t2, t2, t1);
@@ -2261,14 +2266,14 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
         t1 = tcg_temp_new();
         /* Do a byte access to possibly trigger a page
            fault with the unaligned address.  */
-        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
         tcg_gen_andi_tl(t1, t0, 3);
 #ifdef TARGET_WORDS_BIGENDIAN
         tcg_gen_xori_tl(t1, t1, 3);
 #endif
         tcg_gen_shli_tl(t1, t1, 3);
         tcg_gen_andi_tl(t0, t0, ~3);
-        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
+        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
         tcg_gen_shr_tl(t0, t0, t1);
         tcg_gen_xori_tl(t1, t1, 31);
         t2 = tcg_const_tl(0xfffffffeull);
@@ -2283,7 +2288,7 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
         break;
     case OPC_LL:
     case R6_OPC_LL:
-        op_ld_ll(t0, t0, ctx);
+        op_ld_ll(t0, t0, mem_idx, ctx);
         gen_store_gpr(t0, rt);
         break;
     }
@@ -2296,38 +2301,39 @@ static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
 {
     TCGv t0 = tcg_temp_new();
     TCGv t1 = tcg_temp_new();
+    int mem_idx = ctx->mem_idx;
 
     gen_base_offset_addr(ctx, t0, base, offset);
     gen_load_gpr(t1, rt);
     switch (opc) {
 #if defined(TARGET_MIPS64)
     case OPC_SD:
-        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
+        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
                            ctx->default_tcg_memop_mask);
         break;
     case OPC_SDL:
-        gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
+        gen_helper_0e2i(sdl, t1, t0, mem_idx);
         break;
     case OPC_SDR:
-        gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
+        gen_helper_0e2i(sdr, t1, t0, mem_idx);
         break;
 #endif
     case OPC_SW:
-        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
+        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
                            ctx->default_tcg_memop_mask);
         break;
     case OPC_SH:
-        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
+        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
                            ctx->default_tcg_memop_mask);
         break;
     case OPC_SB:
-        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
+        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
         break;
     case OPC_SWL:
-        gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
+        gen_helper_0e2i(swl, t1, t0, mem_idx);
         break;
     case OPC_SWR:
-        gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
+        gen_helper_0e2i(swr, t1, t0, mem_idx);
         break;
     }
     tcg_temp_free(t0);
@@ -2340,6 +2346,7 @@ static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
                          int base, int16_t offset)
 {
     TCGv t0, t1;
+    int mem_idx = ctx->mem_idx;
 
 #ifdef CONFIG_USER_ONLY
     t0 = tcg_temp_local_new();
@@ -2354,12 +2361,12 @@ static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
 #if defined(TARGET_MIPS64)
     case OPC_SCD:
     case R6_OPC_SCD:
-        op_st_scd(t1, t0, rt, ctx);
+        op_st_scd(t1, t0, rt, mem_idx, ctx);
         break;
 #endif
     case OPC_SC:
     case R6_OPC_SC:
-        op_st_sc(t1, t0, rt, ctx);
+        op_st_sc(t1, t0, rt, mem_idx, ctx);
         break;
     }
     tcg_temp_free(t1);
-- 
git-series 0.8.10

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 6/14] target/mips: Decode MIPS32 EVA load & store instructions
  2017-07-18 11:55 [Qemu-devel] [PATCH 0/14] target/mips: Add Enhanced Virtual Addressing (EVA) support James Hogan
                   ` (4 preceding siblings ...)
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 5/14] target/mips: Prepare loads/stores for EVA James Hogan
@ 2017-07-18 11:55 ` James Hogan
  2017-07-18 15:43   ` Yongbok Kim
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 7/14] target/mips: Decode microMIPS " James Hogan
                   ` (8 subsequent siblings)
  14 siblings, 1 reply; 30+ messages in thread
From: James Hogan @ 2017-07-18 11:55 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: qemu-devel, James Hogan, Aurelien Jarno

Implement decoding of MIPS32 EVA loads and stores. These access the user
address space from kernel mode when implemented, so for each instruction
we need to check that EVA is available from Config5.EVA & check for
sufficient COP0 privilege (with the new check_eva()), and then override
the mem_idx used for the operation.

Unfortunately some Loongson 2E instructions use overlapping encodings,
so we must be careful not to prevent those from being decoded when EVA
is absent.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Yongbok Kim <yongbok.kim@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
---
Changes in v2:
- Fix typo in commit message (Yongbok).
- Use sextract32 (Yongbok).
---
 target/mips/translate.c | 106 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 106 insertions(+), 0 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 428f71795a5c..91d57f368a97 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -427,6 +427,24 @@ enum {
     OPC_EXTR_W_DSP     = 0x38 | OPC_SPECIAL3,
     OPC_DEXTR_W_DSP    = 0x3C | OPC_SPECIAL3,
 
+    /* EVA */
+    OPC_LWLE           = 0x19 | OPC_SPECIAL3,
+    OPC_LWRE           = 0x1A | OPC_SPECIAL3,
+    OPC_CACHEE         = 0x1B | OPC_SPECIAL3,
+    OPC_SBE            = 0x1C | OPC_SPECIAL3,
+    OPC_SHE            = 0x1D | OPC_SPECIAL3,
+    OPC_SCE            = 0x1E | OPC_SPECIAL3,
+    OPC_SWE            = 0x1F | OPC_SPECIAL3,
+    OPC_SWLE           = 0x21 | OPC_SPECIAL3,
+    OPC_SWRE           = 0x22 | OPC_SPECIAL3,
+    OPC_PREFE          = 0x23 | OPC_SPECIAL3,
+    OPC_LBUE           = 0x28 | OPC_SPECIAL3,
+    OPC_LHUE           = 0x29 | OPC_SPECIAL3,
+    OPC_LBE            = 0x2C | OPC_SPECIAL3,
+    OPC_LHE            = 0x2D | OPC_SPECIAL3,
+    OPC_LLE            = 0x2E | OPC_SPECIAL3,
+    OPC_LWE            = 0x2F | OPC_SPECIAL3,
+
     /* R6 */
     R6_OPC_PREF        = 0x35 | OPC_SPECIAL3,
     R6_OPC_CACHE       = 0x25 | OPC_SPECIAL3,
@@ -1431,6 +1449,7 @@ typedef struct DisasContext {
     bool bp;
     uint64_t PAMask;
     bool mvh;
+    bool eva;
     int CP0_LLAddr_shift;
     bool ps;
     bool vp;
@@ -2216,29 +2235,47 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
         gen_store_gpr(t0, rt);
         break;
+    case OPC_LWE:
+        mem_idx = MIPS_HFLAG_UM;
+        /* fall through */
     case OPC_LW:
         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
                            ctx->default_tcg_memop_mask);
         gen_store_gpr(t0, rt);
         break;
+    case OPC_LHE:
+        mem_idx = MIPS_HFLAG_UM;
+        /* fall through */
     case OPC_LH:
         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
                            ctx->default_tcg_memop_mask);
         gen_store_gpr(t0, rt);
         break;
+    case OPC_LHUE:
+        mem_idx = MIPS_HFLAG_UM;
+        /* fall through */
     case OPC_LHU:
         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
                            ctx->default_tcg_memop_mask);
         gen_store_gpr(t0, rt);
         break;
+    case OPC_LBE:
+        mem_idx = MIPS_HFLAG_UM;
+        /* fall through */
     case OPC_LB:
         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
         gen_store_gpr(t0, rt);
         break;
+    case OPC_LBUE:
+        mem_idx = MIPS_HFLAG_UM;
+        /* fall through */
     case OPC_LBU:
         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
         gen_store_gpr(t0, rt);
         break;
+    case OPC_LWLE:
+        mem_idx = MIPS_HFLAG_UM;
+        /* fall through */
     case OPC_LWL:
         t1 = tcg_temp_new();
         /* Do a byte access to possibly trigger a page
@@ -2262,6 +2299,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
         tcg_gen_ext32s_tl(t0, t0);
         gen_store_gpr(t0, rt);
         break;
+    case OPC_LWRE:
+        mem_idx = MIPS_HFLAG_UM;
+        /* fall through */
     case OPC_LWR:
         t1 = tcg_temp_new();
         /* Do a byte access to possibly trigger a page
@@ -2286,6 +2326,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
         tcg_gen_ext32s_tl(t0, t0);
         gen_store_gpr(t0, rt);
         break;
+    case OPC_LLE:
+        mem_idx = MIPS_HFLAG_UM;
+        /* fall through */
     case OPC_LL:
     case R6_OPC_LL:
         op_ld_ll(t0, t0, mem_idx, ctx);
@@ -2318,20 +2361,35 @@ static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
         gen_helper_0e2i(sdr, t1, t0, mem_idx);
         break;
 #endif
+    case OPC_SWE:
+        mem_idx = MIPS_HFLAG_UM;
+        /* fall through */
     case OPC_SW:
         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
                            ctx->default_tcg_memop_mask);
         break;
+    case OPC_SHE:
+        mem_idx = MIPS_HFLAG_UM;
+        /* fall through */
     case OPC_SH:
         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
                            ctx->default_tcg_memop_mask);
         break;
+    case OPC_SBE:
+        mem_idx = MIPS_HFLAG_UM;
+        /* fall through */
     case OPC_SB:
         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
         break;
+    case OPC_SWLE:
+        mem_idx = MIPS_HFLAG_UM;
+        /* fall through */
     case OPC_SWL:
         gen_helper_0e2i(swl, t1, t0, mem_idx);
         break;
+    case OPC_SWRE:
+        mem_idx = MIPS_HFLAG_UM;
+        /* fall through */
     case OPC_SWR:
         gen_helper_0e2i(swr, t1, t0, mem_idx);
         break;
@@ -2364,6 +2422,9 @@ static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
         op_st_scd(t1, t0, rt, mem_idx, ctx);
         break;
 #endif
+    case OPC_SCE:
+        mem_idx = MIPS_HFLAG_UM;
+        /* fall through */
     case OPC_SC:
     case R6_OPC_SC:
         op_st_sc(t1, t0, rt, mem_idx, ctx);
@@ -18014,13 +18075,57 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
 {
     int rs, rt, rd, sa;
     uint32_t op1, op2;
+    int16_t imm;
 
     rs = (ctx->opcode >> 21) & 0x1f;
     rt = (ctx->opcode >> 16) & 0x1f;
     rd = (ctx->opcode >> 11) & 0x1f;
     sa = (ctx->opcode >> 6) & 0x1f;
+    imm = sextract32(ctx->opcode, 7, 9);
 
     op1 = MASK_SPECIAL3(ctx->opcode);
+
+    /*
+     * EVA loads and stores overlap Loongson 2E instructions decoded by
+     * decode_opc_special3_legacy(), so be careful to allow their decoding when
+     * EVA is absent.
+     */
+    if (ctx->eva) {
+        switch (op1) {
+        case OPC_LWLE ... OPC_LWRE:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
+            /* fall through */
+        case OPC_LBUE ... OPC_LHUE:
+        case OPC_LBE ... OPC_LWE:
+            check_cp0_enabled(ctx);
+            gen_ld(ctx, op1, rt, rs, imm);
+            return;
+        case OPC_SWLE ... OPC_SWRE:
+            check_insn_opc_removed(ctx, ISA_MIPS32R6);
+            /* fall through */
+        case OPC_SBE ... OPC_SHE:
+        case OPC_SWE:
+            check_cp0_enabled(ctx);
+            gen_st(ctx, op1, rt, rs, imm);
+            return;
+        case OPC_SCE:
+            check_cp0_enabled(ctx);
+            gen_st_cond(ctx, op1, rt, rs, imm);
+            return;
+        case OPC_CACHEE:
+            check_cp0_enabled(ctx);
+            if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
+                gen_cache_operation(ctx, rt, rs, imm);
+            }
+            /* Treat as NOP. */
+            return;
+        case OPC_PREFE:
+            check_cp0_enabled(ctx);
+            /* Treat as NOP. */
+            return;
+        }
+    }
+
     switch (op1) {
     case OPC_EXT:
     case OPC_INS:
@@ -19916,6 +20021,7 @@ void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb)
     ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
     ctx.PAMask = env->PAMask;
     ctx.mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
+    ctx.eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
     ctx.CP0_LLAddr_shift = env->CP0_LLAddr_shift;
     ctx.cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
     /* Restore delay slot state from the tb context.  */
-- 
git-series 0.8.10

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 7/14] target/mips: Decode microMIPS EVA load & store instructions
  2017-07-18 11:55 [Qemu-devel] [PATCH 0/14] target/mips: Add Enhanced Virtual Addressing (EVA) support James Hogan
                   ` (5 preceding siblings ...)
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 6/14] target/mips: Decode MIPS32 EVA load & store instructions James Hogan
@ 2017-07-18 11:55 ` James Hogan
  2017-07-18 16:07   ` Yongbok Kim
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 8/14] target/mips: Check memory permissions with mem_idx James Hogan
                   ` (7 subsequent siblings)
  14 siblings, 1 reply; 30+ messages in thread
From: James Hogan @ 2017-07-18 11:55 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: qemu-devel, James Hogan, Aurelien Jarno

Implement decoding of microMIPS EVA load and store instruction groups in
the POOL31C pool. These use the same gen_ld(), gen_st(), gen_st_cond()
helpers as the MIPS32 decoding, passing the equivalent MIPS32 opcodes as
opc.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Yongbok Kim <yongbok.kim@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
---
Changes in v2:
- New patch (Yongbok).
---
 target/mips/translate.c | 119 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 115 insertions(+), 4 deletions(-)

diff --git a/target/mips/translate.c b/target/mips/translate.c
index 91d57f368a97..9b6963b4e64c 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -12513,19 +12513,45 @@ enum {
     LWR = 0x1,
     SWR = 0x9,
     PREF = 0x2,
-    /* 0xa is reserved */
+    ST_EVA = 0xa,
     LL = 0x3,
     SC = 0xb,
     LDL = 0x4,
     SDL = 0xc,
     LDR = 0x5,
     SDR = 0xd,
-    /* 0x6 is reserved */
+    LD_EVA = 0x6,
     LWU = 0xe,
     LLD = 0x7,
     SCD = 0xf
 };
 
+/* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
+
+enum {
+    LBUE = 0x0,
+    LHUE = 0x1,
+    LWLE = 0x2,
+    LWRE = 0x3,
+    LBE = 0x4,
+    LHE = 0x5,
+    LLE = 0x6,
+    LWE = 0x7,
+};
+
+/* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
+
+enum {
+    SWLE = 0x0,
+    SWRE = 0x1,
+    PREFE = 0x2,
+    CACHEE = 0x3,
+    SBE = 0x4,
+    SHE = 0x5,
+    SCE = 0x6,
+    SWE = 0x7,
+};
+
 /* POOL32F encoding of minor opcode field (bits 5..0) */
 
 enum {
@@ -13826,7 +13852,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
     uint16_t insn;
     int rt, rs, rd, rr;
     int16_t imm;
-    uint32_t op, minor, mips32_op;
+    uint32_t op, minor, minor2, mips32_op;
     uint32_t cond, fmt, cc;
 
     insn = cpu_lduw_code(env, ctx->pc + 2);
@@ -14771,7 +14797,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
             gen_ld(ctx, mips32_op, rt, rs, offset);
             break;
         do_st_lr:
-            gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
+            gen_st(ctx, mips32_op, rt, rs, offset);
             break;
         case SC:
             gen_st_cond(ctx, OPC_SC, rt, rs, offset);
@@ -14783,6 +14809,91 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
             gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
             break;
 #endif
+        case LD_EVA:
+            if (!ctx->eva) {
+                MIPS_INVAL("pool32c ld-eva");
+                generate_exception_end(ctx, EXCP_RI);
+                break;
+            }
+            check_cp0_enabled(ctx);
+
+            minor2 = (ctx->opcode >> 9) & 0x7;
+            offset = sextract32(ctx->opcode, 0, 9);
+            switch (minor2) {
+            case LBUE:
+                mips32_op = OPC_LBUE;
+                goto do_ld_lr;
+            case LHUE:
+                mips32_op = OPC_LHUE;
+                goto do_ld_lr;
+            case LWLE:
+                check_insn_opc_removed(ctx, ISA_MIPS32R6);
+                mips32_op = OPC_LWLE;
+                goto do_ld_lr;
+            case LWRE:
+                check_insn_opc_removed(ctx, ISA_MIPS32R6);
+                mips32_op = OPC_LWRE;
+                goto do_ld_lr;
+            case LBE:
+                mips32_op = OPC_LBE;
+                goto do_ld_lr;
+            case LHE:
+                mips32_op = OPC_LHE;
+                goto do_ld_lr;
+            case LLE:
+                mips32_op = OPC_LLE;
+                goto do_ld_lr;
+            case LWE:
+                mips32_op = OPC_LWE;
+                goto do_ld_lr;
+            };
+            break;
+        case ST_EVA:
+            if (!ctx->eva) {
+                MIPS_INVAL("pool32c st-eva");
+                generate_exception_end(ctx, EXCP_RI);
+                break;
+            }
+            check_cp0_enabled(ctx);
+
+            minor2 = (ctx->opcode >> 9) & 0x7;
+            offset = sextract32(ctx->opcode, 0, 9);
+            switch (minor2) {
+            case SWLE:
+                check_insn_opc_removed(ctx, ISA_MIPS32R6);
+                mips32_op = OPC_SWLE;
+                goto do_st_lr;
+            case SWRE:
+                check_insn_opc_removed(ctx, ISA_MIPS32R6);
+                mips32_op = OPC_SWRE;
+                goto do_st_lr;
+            case PREFE:
+                /* Treat as no-op */
+                if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
+                    /* hint codes 24-31 are reserved and signal RI */
+                    generate_exception(ctx, EXCP_RI);
+                }
+                break;
+            case CACHEE:
+                /* Treat as no-op */
+                if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
+                    gen_cache_operation(ctx, rt, rs, offset);
+                }
+                break;
+            case SBE:
+                mips32_op = OPC_SBE;
+                goto do_st_lr;
+            case SHE:
+                mips32_op = OPC_SHE;
+                goto do_st_lr;
+            case SCE:
+                gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
+                break;
+            case SWE:
+                mips32_op = OPC_SWE;
+                goto do_st_lr;
+            };
+            break;
         case PREF:
             /* Treat as no-op */
             if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
-- 
git-series 0.8.10

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 8/14] target/mips: Check memory permissions with mem_idx
  2017-07-18 11:55 [Qemu-devel] [PATCH 0/14] target/mips: Add Enhanced Virtual Addressing (EVA) support James Hogan
                   ` (6 preceding siblings ...)
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 7/14] target/mips: Decode microMIPS " James Hogan
@ 2017-07-18 11:55 ` James Hogan
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 9/14] target/mips: Abstract mmu_idx from hflags James Hogan
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 30+ messages in thread
From: James Hogan @ 2017-07-18 11:55 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: qemu-devel, James Hogan, Aurelien Jarno

When performing virtual to physical address translation, check the
required privilege level based on the mem_idx rather than the mode in
the hflags. This will allow EVA loads & stores to operate safely only on
user memory from kernel mode.

For the cases where the mmu_idx doesn't need to be overridden
(mips_cpu_get_phys_page_debug() and cpu_mips_translate_address()), we
calculate the required mmu_idx using cpu_mmu_index(). Note that this
only tests the MIPS_HFLAG_KSU bits rather than MIPS_HFLAG_MODE, so we
don't test the debug mode hflag MIPS_HFLAG_DM any longer. This should be
fine as get_physical_address() only compares against MIPS_HFLAG_UM and
MIPS_HFLAG_SM, neither of which should get set by compute_hflags() when
MIPS_HFLAG_DM is set.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Reviewed-by: Yongbok Kim <yongbok.kim@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
---
 target/mips/helper.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/target/mips/helper.c b/target/mips/helper.c
index cd07995eedb2..f78d151d2583 100644
--- a/target/mips/helper.c
+++ b/target/mips/helper.c
@@ -109,11 +109,11 @@ int r4k_map_address (CPUMIPSState *env, hwaddr *physical, int *prot,
 
 static int get_physical_address (CPUMIPSState *env, hwaddr *physical,
                                 int *prot, target_ulong real_address,
-                                int rw, int access_type)
+                                int rw, int access_type, int mmu_idx)
 {
     /* User mode can only access useg/xuseg */
-    int user_mode = (env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM;
-    int supervisor_mode = (env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_SM;
+    int user_mode = mmu_idx == MIPS_HFLAG_UM;
+    int supervisor_mode = mmu_idx == MIPS_HFLAG_SM;
     int kernel_mode = !user_mode && !supervisor_mode;
 #if defined(TARGET_MIPS64)
     int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0;
@@ -413,11 +413,12 @@ static void raise_mmu_exception(CPUMIPSState *env, target_ulong address,
 hwaddr mips_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 {
     MIPSCPU *cpu = MIPS_CPU(cs);
+    CPUMIPSState *env = &cpu->env;
     hwaddr phys_addr;
     int prot;
 
-    if (get_physical_address(&cpu->env, &phys_addr, &prot, addr, 0,
-                             ACCESS_INT) != 0) {
+    if (get_physical_address(env, &phys_addr, &prot, addr, 0, ACCESS_INT,
+                             cpu_mmu_index(env, false)) != 0) {
         return -1;
     }
     return phys_addr;
@@ -449,7 +450,7 @@ int mips_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
        correctly */
     access_type = ACCESS_INT;
     ret = get_physical_address(env, &physical, &prot,
-                               address, rw, access_type);
+                               address, rw, access_type, mmu_idx);
     switch (ret) {
     case TLBRET_MATCH:
         qemu_log_mask(CPU_LOG_MMU,
@@ -487,8 +488,8 @@ hwaddr cpu_mips_translate_address(CPUMIPSState *env, target_ulong address, int r
 
     /* data access */
     access_type = ACCESS_INT;
-    ret = get_physical_address(env, &physical, &prot,
-                               address, rw, access_type);
+    ret = get_physical_address(env, &physical, &prot, address, rw, access_type,
+                               cpu_mmu_index(env, false));
     if (ret != TLBRET_MATCH) {
         raise_mmu_exception(env, address, rw, ret);
         return -1LL;
-- 
git-series 0.8.10

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 9/14] target/mips: Abstract mmu_idx from hflags
  2017-07-18 11:55 [Qemu-devel] [PATCH 0/14] target/mips: Add Enhanced Virtual Addressing (EVA) support James Hogan
                   ` (7 preceding siblings ...)
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 8/14] target/mips: Check memory permissions with mem_idx James Hogan
@ 2017-07-18 11:55 ` James Hogan
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 10/14] target/mips: Add an MMU mode for ERL James Hogan
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 30+ messages in thread
From: James Hogan @ 2017-07-18 11:55 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: qemu-devel, James Hogan, Aurelien Jarno

The MIPS mmu_idx is sometimes calculated from hflags without an env
pointer available as cpu_mmu_index() requires.

Create a common hflags_mmu_index() for the purpose of this calculation
which can operate on any hflags, not just with an env pointer, and
update cpu_mmu_index() itself and gen_intermediate_code() to use it.

Also update debug_post_eret() and helper_mtc0_status() to log the MMU
mode with the status change (SM, UM, or nothing for kernel mode) based
on cpu_mmu_index() rather than directly testing hflags.

This will also allow the logic to be more easily updated when a new MMU
mode is added.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Reviewed-by: Yongbok Kim <yongbok.kim@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
---
Changes in v2:
- Also convert reference to hflags & MIPS_HFLAG_KSU in op_helper.c to
  cpu_mmu_index (Yongbok).
---
 target/mips/cpu.h       | 8 +++++++-
 target/mips/op_helper.c | 4 ++--
 target/mips/translate.c | 2 +-
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 2b699a0e2456..3cf167611599 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -699,9 +699,15 @@ extern uint32_t cpu_rddsp(uint32_t mask_num, CPUMIPSState *env);
 #define MMU_MODE1_SUFFIX _super
 #define MMU_MODE2_SUFFIX _user
 #define MMU_USER_IDX 2
+
+static inline int hflags_mmu_index(uint32_t hflags)
+{
+    return hflags & MIPS_HFLAG_KSU;
+}
+
 static inline int cpu_mmu_index (CPUMIPSState *env, bool ifetch)
 {
-    return env->hflags & MIPS_HFLAG_KSU;
+    return hflags_mmu_index(env->hflags);
 }
 
 static inline bool cpu_mips_hw_interrupts_enabled(CPUMIPSState *env)
diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index ba8b159d3bac..94172bcfe32a 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -1450,7 +1450,7 @@ void helper_mtc0_status(CPUMIPSState *env, target_ulong arg1)
                 old, old & env->CP0_Cause & CP0Ca_IP_mask,
                 val, val & env->CP0_Cause & CP0Ca_IP_mask,
                 env->CP0_Cause);
-        switch (env->hflags & MIPS_HFLAG_KSU) {
+        switch (cpu_mmu_index(env, false)) {
         case MIPS_HFLAG_UM: qemu_log(", UM\n"); break;
         case MIPS_HFLAG_SM: qemu_log(", SM\n"); break;
         case MIPS_HFLAG_KM: qemu_log("\n"); break;
@@ -2244,7 +2244,7 @@ static void debug_post_eret(CPUMIPSState *env)
             qemu_log(" ErrorEPC " TARGET_FMT_lx, env->CP0_ErrorEPC);
         if (env->hflags & MIPS_HFLAG_DM)
             qemu_log(" DEPC " TARGET_FMT_lx, env->CP0_DEPC);
-        switch (env->hflags & MIPS_HFLAG_KSU) {
+        switch (cpu_mmu_index(env, false)) {
         case MIPS_HFLAG_UM: qemu_log(", UM\n"); break;
         case MIPS_HFLAG_SM: qemu_log(", SM\n"); break;
         case MIPS_HFLAG_KM: qemu_log("\n"); break;
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 9b6963b4e64c..ac9023443112 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -20148,7 +20148,7 @@ void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb)
 #ifdef CONFIG_USER_ONLY
         ctx.mem_idx = MIPS_HFLAG_UM;
 #else
-        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
+        ctx.mem_idx = hflags_mmu_index(ctx.hflags);
 #endif
     ctx.default_tcg_memop_mask = (ctx.insn_flags & ISA_MIPS32R6) ?
                                  MO_UNALN : MO_ALIGN;
-- 
git-series 0.8.10

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 10/14] target/mips: Add an MMU mode for ERL
  2017-07-18 11:55 [Qemu-devel] [PATCH 0/14] target/mips: Add Enhanced Virtual Addressing (EVA) support James Hogan
                   ` (8 preceding siblings ...)
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 9/14] target/mips: Abstract mmu_idx from hflags James Hogan
@ 2017-07-18 11:55 ` James Hogan
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 11/14] target/mips: Add segmentation control registers James Hogan
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 30+ messages in thread
From: James Hogan @ 2017-07-18 11:55 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: qemu-devel, James Hogan, Aurelien Jarno

The segmentation control feature allows a legacy memory segment to
become unmapped uncached at error level (according to CP0_Status.ERL),
and in fact the user segment is already treated in this way by QEMU.

Add a new MMU mode for this state so that QEMU's mappings don't persist
between ERL=0 and ERL=1.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Reviewed-by: Yongbok Kim <yongbok.kim@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
---
Changes in v2:
- Add ERL case to log output where cpu_mmu_index() is now used in
  op_helper.c
---
 target/mips/cpu.h       | 17 +++++++++++++----
 target/mips/op_helper.c |  4 ++++
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 3cf167611599..c24b1f64c685 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -134,7 +134,7 @@ struct CPUMIPSFPUContext {
 #define FP_UNIMPLEMENTED  32
 };
 
-#define NB_MMU_MODES 3
+#define NB_MMU_MODES 4
 #define TARGET_INSN_START_EXTRA_WORDS 2
 
 typedef struct CPUMIPSMVPContext CPUMIPSMVPContext;
@@ -551,7 +551,7 @@ struct CPUMIPSState {
 #define EXCP_INST_NOTAVAIL 0x2 /* No valid instruction word for BadInstr */
     uint32_t hflags;    /* CPU State */
     /* TMASK defines different execution modes */
-#define MIPS_HFLAG_TMASK  0xF5807FF
+#define MIPS_HFLAG_TMASK  0x1F5807FF
 #define MIPS_HFLAG_MODE   0x00007 /* execution modes                    */
     /* The KSU flags must be the lowest bits in hflags. The flag order
        must be the same as defined for CP0 Status. This allows to use
@@ -601,6 +601,7 @@ struct CPUMIPSState {
 #define MIPS_HFLAG_FRE   0x2000000 /* FRE enabled */
 #define MIPS_HFLAG_ELPA  0x4000000
 #define MIPS_HFLAG_ITC_CACHE  0x8000000 /* CACHE instr. operates on ITC tag */
+#define MIPS_HFLAG_ERL   0x10000000 /* error level flag */
     target_ulong btarget;        /* Jump / branch target               */
     target_ulong bcond;          /* Branch condition (if needed)       */
 
@@ -698,11 +699,16 @@ extern uint32_t cpu_rddsp(uint32_t mask_num, CPUMIPSState *env);
 #define MMU_MODE0_SUFFIX _kernel
 #define MMU_MODE1_SUFFIX _super
 #define MMU_MODE2_SUFFIX _user
+#define MMU_MODE3_SUFFIX _error
 #define MMU_USER_IDX 2
 
 static inline int hflags_mmu_index(uint32_t hflags)
 {
-    return hflags & MIPS_HFLAG_KSU;
+    if (hflags & MIPS_HFLAG_ERL) {
+        return 3; /* ERL */
+    } else {
+        return hflags & MIPS_HFLAG_KSU;
+    }
 }
 
 static inline int cpu_mmu_index (CPUMIPSState *env, bool ifetch)
@@ -971,7 +977,10 @@ static inline void compute_hflags(CPUMIPSState *env)
                      MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU |
                      MIPS_HFLAG_AWRAP | MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2 |
                      MIPS_HFLAG_SBRI | MIPS_HFLAG_MSA | MIPS_HFLAG_FRE |
-                     MIPS_HFLAG_ELPA);
+                     MIPS_HFLAG_ELPA | MIPS_HFLAG_ERL);
+    if (env->CP0_Status & (1 << CP0St_ERL)) {
+        env->hflags |= MIPS_HFLAG_ERL;
+    }
     if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
         !(env->CP0_Status & (1 << CP0St_ERL)) &&
         !(env->hflags & MIPS_HFLAG_DM)) {
diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index 94172bcfe32a..e3531b6e84b0 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -67,6 +67,7 @@ static inline type do_##name(CPUMIPSState *env, target_ulong addr,      \
     case 1: return (type) cpu_##insn##_super_ra(env, addr, retaddr);    \
     default:                                                            \
     case 2: return (type) cpu_##insn##_user_ra(env, addr, retaddr);     \
+    case 3: return (type) cpu_##insn##_error_ra(env, addr, retaddr);    \
     }                                                                   \
 }
 #endif
@@ -94,6 +95,7 @@ static inline void do_##name(CPUMIPSState *env, target_ulong addr,      \
     case 1: cpu_##insn##_super_ra(env, addr, val, retaddr); break;      \
     default:                                                            \
     case 2: cpu_##insn##_user_ra(env, addr, val, retaddr); break;       \
+    case 3: cpu_##insn##_error_ra(env, addr, val, retaddr); break;      \
     }                                                                   \
 }
 #endif
@@ -1451,6 +1453,7 @@ void helper_mtc0_status(CPUMIPSState *env, target_ulong arg1)
                 val, val & env->CP0_Cause & CP0Ca_IP_mask,
                 env->CP0_Cause);
         switch (cpu_mmu_index(env, false)) {
+        case 3: qemu_log(", ERL\n"); break;
         case MIPS_HFLAG_UM: qemu_log(", UM\n"); break;
         case MIPS_HFLAG_SM: qemu_log(", SM\n"); break;
         case MIPS_HFLAG_KM: qemu_log("\n"); break;
@@ -2245,6 +2248,7 @@ static void debug_post_eret(CPUMIPSState *env)
         if (env->hflags & MIPS_HFLAG_DM)
             qemu_log(" DEPC " TARGET_FMT_lx, env->CP0_DEPC);
         switch (cpu_mmu_index(env, false)) {
+        case 3: qemu_log(", ERL\n"); break;
         case MIPS_HFLAG_UM: qemu_log(", UM\n"); break;
         case MIPS_HFLAG_SM: qemu_log(", SM\n"); break;
         case MIPS_HFLAG_KM: qemu_log("\n"); break;
-- 
git-series 0.8.10

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 11/14] target/mips: Add segmentation control registers
  2017-07-18 11:55 [Qemu-devel] [PATCH 0/14] target/mips: Add Enhanced Virtual Addressing (EVA) support James Hogan
                   ` (9 preceding siblings ...)
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 10/14] target/mips: Add an MMU mode for ERL James Hogan
@ 2017-07-18 11:55 ` James Hogan
  2017-07-18 22:01   ` Yongbok Kim
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 12/14] target/mips: Implement segmentation control James Hogan
                   ` (3 subsequent siblings)
  14 siblings, 1 reply; 30+ messages in thread
From: James Hogan @ 2017-07-18 11:55 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: qemu-devel, James Hogan, Aurelien Jarno

The optional segmentation control registers CP0_SegCtl0, CP0_SegCtl1 &
CP0_SegCtl2 control the behaviour and required privilege of the legacy
virtual memory segments.

Add them to the CP0 interface so they can be read and written when
CP0_Config3.SC=1, and initialise them to describe the standard legacy
layout so they can be used in future patches regardless of whether they
are exposed to the guest.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Yongbok Kim <yongbok.kim@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
---
Changes in v2:
- Use ld_tl and ext32s_tl rather than ld32s_tl to avoid big endian host,
  MIPS64 target issues (Yongbok).
- Add missing break in DMFC0 CP0_SegCtl2 case.
---
 target/mips/cpu.h       | 30 ++++++++++++++-
 target/mips/helper.h    |  3 +-
 target/mips/machine.c   |  7 ++-
 target/mips/op_helper.c | 24 +++++++++++-
 target/mips/translate.c | 88 ++++++++++++++++++++++++++++++++++++++++++-
 5 files changed, 150 insertions(+), 2 deletions(-)

diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index c24b1f64c685..74f6a5b09806 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -306,6 +306,36 @@ struct CPUMIPSState {
 #define CP0PG_XIE 30
 #define CP0PG_ELPA 29
 #define CP0PG_IEC 27
+    target_ulong CP0_SegCtl0;
+    target_ulong CP0_SegCtl1;
+    target_ulong CP0_SegCtl2;
+#define CP0SC_PA        9
+#define CP0SC_PA_MASK   (0x7FULL << CP0SC_PA)
+#define CP0SC_PA_1GMASK (0x7EULL << CP0SC_PA)
+#define CP0SC_AM        4
+#define CP0SC_AM_MASK   (0x7ULL << CP0SC_AM)
+#define CP0SC_AM_UK     0ULL
+#define CP0SC_AM_MK     1ULL
+#define CP0SC_AM_MSK    2ULL
+#define CP0SC_AM_MUSK   3ULL
+#define CP0SC_AM_MUSUK  4ULL
+#define CP0SC_AM_USK    5ULL
+#define CP0SC_AM_UUSK   7ULL
+#define CP0SC_EU        3
+#define CP0SC_EU_MASK   (1ULL << CP0SC_EU)
+#define CP0SC_C         0
+#define CP0SC_C_MASK    (0x7ULL << CP0SC_C)
+#define CP0SC_MASK      (CP0SC_C_MASK | CP0SC_EU_MASK | CP0SC_AM_MASK | \
+                         CP0SC_PA_MASK)
+#define CP0SC_1GMASK    (CP0SC_C_MASK | CP0SC_EU_MASK | CP0SC_AM_MASK | \
+                         CP0SC_PA_1GMASK)
+#define CP0SC0_MASK     (CP0SC_MASK | (CP0SC_MASK << 16))
+#define CP0SC1_XAM      59
+#define CP0SC1_XAM_MASK (0x7ULL << CP0SC1_XAM)
+#define CP0SC1_MASK     (CP0SC_MASK | (CP0SC_MASK << 16) | CP0SC1_XAM_MASK)
+#define CP0SC2_XR       56
+#define CP0SC2_XR_MASK  (0xFFULL << CP0SC2_XR)
+#define CP0SC2_MASK     (CP0SC_1GMASK | (CP0SC_1GMASK << 16) | CP0SC2_XR_MASK)
     int32_t CP0_Wired;
     int32_t CP0_SRSConf0_rw_bitmask;
     int32_t CP0_SRSConf0;
diff --git a/target/mips/helper.h b/target/mips/helper.h
index 60efa01194a0..5f492348ddfa 100644
--- a/target/mips/helper.h
+++ b/target/mips/helper.h
@@ -115,6 +115,9 @@ DEF_HELPER_2(mtc0_entrylo1, void, env, tl)
 DEF_HELPER_2(mtc0_context, void, env, tl)
 DEF_HELPER_2(mtc0_pagemask, void, env, tl)
 DEF_HELPER_2(mtc0_pagegrain, void, env, tl)
+DEF_HELPER_2(mtc0_segctl0, void, env, tl)
+DEF_HELPER_2(mtc0_segctl1, void, env, tl)
+DEF_HELPER_2(mtc0_segctl2, void, env, tl)
 DEF_HELPER_2(mtc0_wired, void, env, tl)
 DEF_HELPER_2(mtc0_srsconf0, void, env, tl)
 DEF_HELPER_2(mtc0_srsconf1, void, env, tl)
diff --git a/target/mips/machine.c b/target/mips/machine.c
index 91e31a7c2fe8..898825de3b9c 100644
--- a/target/mips/machine.c
+++ b/target/mips/machine.c
@@ -211,8 +211,8 @@ const VMStateDescription vmstate_tlb = {
 
 const VMStateDescription vmstate_mips_cpu = {
     .name = "cpu",
-    .version_id = 9,
-    .minimum_version_id = 9,
+    .version_id = 10,
+    .minimum_version_id = 10,
     .post_load = cpu_post_load,
     .fields = (VMStateField[]) {
         /* Active TC */
@@ -252,6 +252,9 @@ const VMStateDescription vmstate_mips_cpu = {
         VMSTATE_UINTTL(env.CP0_Context, MIPSCPU),
         VMSTATE_INT32(env.CP0_PageMask, MIPSCPU),
         VMSTATE_INT32(env.CP0_PageGrain, MIPSCPU),
+        VMSTATE_UINTTL(env.CP0_SegCtl0, MIPSCPU),
+        VMSTATE_UINTTL(env.CP0_SegCtl1, MIPSCPU),
+        VMSTATE_UINTTL(env.CP0_SegCtl2, MIPSCPU),
         VMSTATE_INT32(env.CP0_Wired, MIPSCPU),
         VMSTATE_INT32(env.CP0_SRSConf0, MIPSCPU),
         VMSTATE_INT32(env.CP0_SRSConf1, MIPSCPU),
diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index e3531b6e84b0..d0bf819fa9fd 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -1320,6 +1320,30 @@ void helper_mtc0_pagegrain(CPUMIPSState *env, target_ulong arg1)
     restore_pamask(env);
 }
 
+void helper_mtc0_segctl0(CPUMIPSState *env, target_ulong arg1)
+{
+    CPUState *cs = CPU(mips_env_get_cpu(env));
+
+    env->CP0_SegCtl0 = arg1 & CP0SC0_MASK;
+    tlb_flush(cs);
+}
+
+void helper_mtc0_segctl1(CPUMIPSState *env, target_ulong arg1)
+{
+    CPUState *cs = CPU(mips_env_get_cpu(env));
+
+    env->CP0_SegCtl1 = arg1 & CP0SC1_MASK;
+    tlb_flush(cs);
+}
+
+void helper_mtc0_segctl2(CPUMIPSState *env, target_ulong arg1)
+{
+    CPUState *cs = CPU(mips_env_get_cpu(env));
+
+    env->CP0_SegCtl2 = arg1 & CP0SC2_MASK;
+    tlb_flush(cs);
+}
+
 void helper_mtc0_wired(CPUMIPSState *env, target_ulong arg1)
 {
     if (env->insn_flags & ISA_MIPS32R6) {
diff --git a/target/mips/translate.c b/target/mips/translate.c
index ac9023443112..5c39fddfc410 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -1450,6 +1450,7 @@ typedef struct DisasContext {
     uint64_t PAMask;
     bool mvh;
     bool eva;
+    bool sc;
     int CP0_LLAddr_shift;
     bool ps;
     bool vp;
@@ -5226,6 +5227,24 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
             rn = "PageGrain";
             break;
+        case 2:
+            CP0_CHECK(ctx->sc);
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
+            tcg_gen_ext32s_tl(arg, arg);
+            rn = "SegCtl0";
+            break;
+        case 3:
+            CP0_CHECK(ctx->sc);
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
+            tcg_gen_ext32s_tl(arg, arg);
+            rn = "SegCtl1";
+            break;
+        case 4:
+            CP0_CHECK(ctx->sc);
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
+            tcg_gen_ext32s_tl(arg, arg);
+            rn = "SegCtl2";
+            break;
         default:
             goto cp0_unimplemented;
         }
@@ -5880,6 +5899,21 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
             rn = "PageGrain";
             ctx->bstate = BS_STOP;
             break;
+        case 2:
+            CP0_CHECK(ctx->sc);
+            gen_helper_mtc0_segctl0(cpu_env, arg);
+            rn = "SegCtl0";
+            break;
+        case 3:
+            CP0_CHECK(ctx->sc);
+            gen_helper_mtc0_segctl1(cpu_env, arg);
+            rn = "SegCtl1";
+            break;
+        case 4:
+            CP0_CHECK(ctx->sc);
+            gen_helper_mtc0_segctl2(cpu_env, arg);
+            rn = "SegCtl2";
+            break;
         default:
             goto cp0_unimplemented;
         }
@@ -6541,6 +6575,21 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
             rn = "PageGrain";
             break;
+        case 2:
+            CP0_CHECK(ctx->sc);
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
+            rn = "SegCtl0";
+            break;
+        case 3:
+            CP0_CHECK(ctx->sc);
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
+            rn = "SegCtl1";
+            break;
+        case 4:
+            CP0_CHECK(ctx->sc);
+            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
+            rn = "SegCtl2";
+            break;
         default:
             goto cp0_unimplemented;
         }
@@ -7177,6 +7226,21 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
             gen_helper_mtc0_pagegrain(cpu_env, arg);
             rn = "PageGrain";
             break;
+        case 2:
+            CP0_CHECK(ctx->sc);
+            gen_helper_mtc0_segctl0(cpu_env, arg);
+            rn = "SegCtl0";
+            break;
+        case 3:
+            CP0_CHECK(ctx->sc);
+            gen_helper_mtc0_segctl1(cpu_env, arg);
+            rn = "SegCtl1";
+            break;
+        case 4:
+            CP0_CHECK(ctx->sc);
+            gen_helper_mtc0_segctl2(cpu_env, arg);
+            rn = "SegCtl2";
+            break;
         default:
             goto cp0_unimplemented;
         }
@@ -20133,6 +20197,7 @@ void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb)
     ctx.PAMask = env->PAMask;
     ctx.mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
     ctx.eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
+    ctx.sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
     ctx.CP0_LLAddr_shift = env->CP0_LLAddr_shift;
     ctx.cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
     /* Restore delay slot state from the tb context.  */
@@ -20619,6 +20684,29 @@ void cpu_state_reset(CPUMIPSState *env)
             env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
         }
     }
+
+    /*
+     * Configure default legacy segmentation control. We use this regardless of
+     * whether segmentation control is presented to the guest.
+     */
+    /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
+    env->CP0_SegCtl0 =   (CP0SC_AM_MK << CP0SC_AM);
+    /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
+    env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
+    /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
+    env->CP0_SegCtl1 =   (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
+                         (2 << CP0SC_C);
+    /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
+    env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
+                         (3 << CP0SC_C)) << 16;
+    /* USeg (seg4 0x40000000..0x7FFFFFFF) */
+    env->CP0_SegCtl2 =   (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
+                         (1 << CP0SC_EU) | (2 << CP0SC_C);
+    /* USeg (seg5 0x00000000..0x3FFFFFFF) */
+    env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
+                         (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
+    /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
+    env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
 #endif
     if ((env->insn_flags & ISA_MIPS32R6) &&
         (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
-- 
git-series 0.8.10

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 12/14] target/mips: Implement segmentation control
  2017-07-18 11:55 [Qemu-devel] [PATCH 0/14] target/mips: Add Enhanced Virtual Addressing (EVA) support James Hogan
                   ` (10 preceding siblings ...)
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 11/14] target/mips: Add segmentation control registers James Hogan
@ 2017-07-18 11:55 ` James Hogan
  2017-07-20 13:08   ` Yongbok Kim
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 13/14] target/mips: Add EVA support to P5600 James Hogan
                   ` (2 subsequent siblings)
  14 siblings, 1 reply; 30+ messages in thread
From: James Hogan @ 2017-07-18 11:55 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: qemu-devel, James Hogan, Aurelien Jarno

Implement the optional segmentation control feature in the virtual to
physical address translation code.

The fixed legacy segment and xkphys handling is replaced with a dynamic
layout based on the segmentation control registers (which should be set
up even when the feature is not exposed to the guest).

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Yongbok Kim <yongbok.kim@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
---
Changes in v2:
- Use hwaddr instead of target_ulong for physical addresses in
  get_seg[ctl]_physical_address() (Yongbok).
- Fix xkphys privilege control based on access mode (am) (Yongbok).
- Fix xkphys TLB faults to use XTLB.
---
 target/mips/helper.c | 177 +++++++++++++++++++++++++++++++++++---------
 1 file changed, 142 insertions(+), 35 deletions(-)

diff --git a/target/mips/helper.c b/target/mips/helper.c
index f78d151d2583..5cb3aa0d5395 100644
--- a/target/mips/helper.c
+++ b/target/mips/helper.c
@@ -107,15 +107,107 @@ int r4k_map_address (CPUMIPSState *env, hwaddr *physical, int *prot,
     return TLBRET_NOMATCH;
 }
 
+static int is_seg_am_mapped(unsigned int am, bool eu, int mmu_idx)
+{
+    /*
+     * Interpret access control mode and mmu_idx.
+     *           AdE?     TLB?
+     *      AM  K S U E  K S U E
+     * UK    0  0 1 1 0  0 - - 0
+     * MK    1  0 1 1 0  1 - - !eu
+     * MSK   2  0 0 1 0  1 1 - !eu
+     * MUSK  3  0 0 0 0  1 1 1 !eu
+     * MUSUK 4  0 0 0 0  0 1 1 0
+     * USK   5  0 0 1 0  0 0 - 0
+     * -     6  - - - -  - - - -
+     * UUSK  7  0 0 0 0  0 0 0 0
+     */
+    int32_t adetlb_mask;
+
+    switch (mmu_idx) {
+    case 3 /* ERL */:
+        /* If EU is set, always unmapped */
+        if (eu) {
+            return 0;
+        }
+        /* fall through */
+    case MIPS_HFLAG_KM:
+        /* Never AdE, TLB mapped if AM={1,2,3} */
+        adetlb_mask = 0x70000000;
+        goto check_tlb;
+
+    case MIPS_HFLAG_SM:
+        /* AdE if AM={0,1}, TLB mapped if AM={2,3,4} */
+        adetlb_mask = 0xc0380000;
+        goto check_ade;
+
+    case MIPS_HFLAG_UM:
+        /* AdE if AM={0,1,2,5}, TLB mapped if AM={3,4} */
+        adetlb_mask = 0xe4180000;
+        /* fall through */
+    check_ade:
+        /* does this AM cause AdE in current execution mode */
+        if ((adetlb_mask << am) < 0) {
+            return TLBRET_BADADDR;
+        }
+        adetlb_mask <<= 8;
+        /* fall through */
+    check_tlb:
+        /* is this AM mapped in current execution mode */
+        return ((adetlb_mask << am) < 0);
+    default:
+        assert(0);
+        return TLBRET_BADADDR;
+    };
+}
+
+static int get_seg_physical_address(CPUMIPSState *env, hwaddr *physical,
+                                    int *prot, target_ulong real_address,
+                                    int rw, int access_type, int mmu_idx,
+                                    unsigned int am, bool eu,
+                                    target_ulong segmask,
+                                    hwaddr physical_base)
+{
+    int mapped = is_seg_am_mapped(am, eu, mmu_idx);
+
+    if (mapped < 0) {
+        /* is_seg_am_mapped can report TLBRET_BADADDR */
+        return mapped;
+    } else if (mapped) {
+        /* The segment is TLB mapped */
+        return env->tlb->map_address(env, physical, prot, real_address, rw,
+                                     access_type);
+    } else {
+        /* The segment is unmapped */
+        *physical = physical_base | (real_address & segmask);
+        *prot = PAGE_READ | PAGE_WRITE;
+        return TLBRET_MATCH;
+    }
+}
+
+static int get_segctl_physical_address(CPUMIPSState *env, hwaddr *physical,
+                                       int *prot, target_ulong real_address,
+                                       int rw, int access_type, int mmu_idx,
+                                       uint16_t segctl, target_ulong segmask)
+{
+    unsigned int am = (segctl & CP0SC_AM_MASK) >> CP0SC_AM;
+    bool eu = (segctl >> CP0SC_EU) & 1;
+    hwaddr pa = ((hwaddr)segctl & CP0SC_PA_MASK) << 20;
+
+    return get_seg_physical_address(env, physical, prot, real_address, rw,
+                                    access_type, mmu_idx, am, eu, segmask,
+                                    pa & ~(hwaddr)segmask);
+}
+
 static int get_physical_address (CPUMIPSState *env, hwaddr *physical,
                                 int *prot, target_ulong real_address,
                                 int rw, int access_type, int mmu_idx)
 {
     /* User mode can only access useg/xuseg */
+#if defined(TARGET_MIPS64)
     int user_mode = mmu_idx == MIPS_HFLAG_UM;
     int supervisor_mode = mmu_idx == MIPS_HFLAG_SM;
     int kernel_mode = !user_mode && !supervisor_mode;
-#if defined(TARGET_MIPS64)
     int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0;
     int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0;
     int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0;
@@ -148,12 +240,16 @@ static int get_physical_address (CPUMIPSState *env, hwaddr *physical,
 
     if (address <= USEG_LIMIT) {
         /* useg */
-        if (env->CP0_Status & (1 << CP0St_ERL)) {
-            *physical = address & 0xFFFFFFFF;
-            *prot = PAGE_READ | PAGE_WRITE;
+        uint16_t segctl;
+
+        if (address >= 0x40000000UL) {
+            segctl = env->CP0_SegCtl2;
         } else {
-            ret = env->tlb->map_address(env, physical, prot, real_address, rw, access_type);
+            segctl = env->CP0_SegCtl2 >> 16;
         }
+        ret = get_segctl_physical_address(env, physical, prot, real_address, rw,
+                                          access_type, mmu_idx, segctl,
+                                          0x3FFFFFFF);
 #if defined(TARGET_MIPS64)
     } else if (address < 0x4000000000000000ULL) {
         /* xuseg */
@@ -172,10 +268,33 @@ static int get_physical_address (CPUMIPSState *env, hwaddr *physical,
         }
     } else if (address < 0xC000000000000000ULL) {
         /* xkphys */
-        if (kernel_mode && KX &&
-            (address & 0x07FFFFFFFFFFFFFFULL) <= env->PAMask) {
-            *physical = address & env->PAMask;
-            *prot = PAGE_READ | PAGE_WRITE;
+        if ((address & 0x07FFFFFFFFFFFFFFULL) <= env->PAMask) {
+            /* KX/SX/UX bit to check for each xkphys EVA access mode */
+            static const uint8_t am_ksux[8] = {
+                [CP0SC_AM_UK]    = (1u << CP0St_KX),
+                [CP0SC_AM_MK]    = (1u << CP0St_KX),
+                [CP0SC_AM_MSK]   = (1u << CP0St_SX),
+                [CP0SC_AM_MUSK]  = (1u << CP0St_UX),
+                [CP0SC_AM_MUSUK] = (1u << CP0St_UX),
+                [CP0SC_AM_USK]   = (1u << CP0St_SX),
+                [6]              = (1u << CP0St_KX),
+                [CP0SC_AM_UUSK]  = (1u << CP0St_UX),
+            };
+            unsigned int am = CP0SC_AM_UK;
+            unsigned int xr = (env->CP0_SegCtl2 & CP0SC2_XR_MASK) >> CP0SC2_XR;
+
+            if (xr & (1 << ((address >> 59) & 0x7))) {
+                am = (env->CP0_SegCtl1 & CP0SC1_XAM_MASK) >> CP0SC1_XAM;
+            }
+            /* Does CP0_Status.KX/SX/UX permit the access mode (am) */
+            if (env->CP0_Status & am_ksux[am]) {
+                ret = get_seg_physical_address(env, physical, prot,
+                                               real_address, rw, access_type,
+                                               mmu_idx, am, false, env->PAMask,
+                                               0);
+            } else {
+                ret = TLBRET_BADADDR;
+            }
         } else {
             ret = TLBRET_BADADDR;
         }
@@ -190,35 +309,25 @@ static int get_physical_address (CPUMIPSState *env, hwaddr *physical,
 #endif
     } else if (address < (int32_t)KSEG1_BASE) {
         /* kseg0 */
-        if (kernel_mode) {
-            *physical = address - (int32_t)KSEG0_BASE;
-            *prot = PAGE_READ | PAGE_WRITE;
-        } else {
-            ret = TLBRET_BADADDR;
-        }
+        ret = get_segctl_physical_address(env, physical, prot, real_address, rw,
+                                          access_type, mmu_idx,
+                                          env->CP0_SegCtl1 >> 16, 0x1FFFFFFF);
     } else if (address < (int32_t)KSEG2_BASE) {
         /* kseg1 */
-        if (kernel_mode) {
-            *physical = address - (int32_t)KSEG1_BASE;
-            *prot = PAGE_READ | PAGE_WRITE;
-        } else {
-            ret = TLBRET_BADADDR;
-        }
+        ret = get_segctl_physical_address(env, physical, prot, real_address, rw,
+                                          access_type, mmu_idx,
+                                          env->CP0_SegCtl1, 0x1FFFFFFF);
     } else if (address < (int32_t)KSEG3_BASE) {
         /* sseg (kseg2) */
-        if (supervisor_mode || kernel_mode) {
-            ret = env->tlb->map_address(env, physical, prot, real_address, rw, access_type);
-        } else {
-            ret = TLBRET_BADADDR;
-        }
+        ret = get_segctl_physical_address(env, physical, prot, real_address, rw,
+                                          access_type, mmu_idx,
+                                          env->CP0_SegCtl0 >> 16, 0x1FFFFFFF);
     } else {
         /* kseg3 */
         /* XXX: debug segment is not emulated */
-        if (kernel_mode) {
-            ret = env->tlb->map_address(env, physical, prot, real_address, rw, access_type);
-        } else {
-            ret = TLBRET_BADADDR;
-        }
+        ret = get_segctl_physical_address(env, physical, prot, real_address, rw,
+                                          access_type, mmu_idx,
+                                          env->CP0_SegCtl0, 0x1FFFFFFF);
     }
     return ret;
 }
@@ -720,10 +829,9 @@ void mips_cpu_do_interrupt(CPUState *cs)
 #if defined(TARGET_MIPS64)
             int R = env->CP0_BadVAddr >> 62;
             int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0;
-            int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0;
             int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0;
 
-            if (((R == 0 && UX) || (R == 1 && SX) || (R == 3 && KX)) &&
+            if ((R != 0 || UX) && (R != 3 || KX) &&
                 (!(env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F))))
                 offset = 0x080;
             else
@@ -739,10 +847,9 @@ void mips_cpu_do_interrupt(CPUState *cs)
 #if defined(TARGET_MIPS64)
             int R = env->CP0_BadVAddr >> 62;
             int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0;
-            int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0;
             int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0;
 
-            if (((R == 0 && UX) || (R == 1 && SX) || (R == 3 && KX)) &&
+            if ((R != 0 || UX) && (R != 3 || KX) &&
                 (!(env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F))))
                 offset = 0x080;
             else
-- 
git-series 0.8.10

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 13/14] target/mips: Add EVA support to P5600
  2017-07-18 11:55 [Qemu-devel] [PATCH 0/14] target/mips: Add Enhanced Virtual Addressing (EVA) support James Hogan
                   ` (11 preceding siblings ...)
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 12/14] target/mips: Implement segmentation control James Hogan
@ 2017-07-18 11:55 ` James Hogan
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 14/14] target/mips: Enable CP0_EBase.WG on MIPS64 CPUs James Hogan
  2017-07-18 21:21 ` [Qemu-devel] [PATCH 0/14] target/mips: Add Enhanced Virtual Addressing (EVA) support no-reply
  14 siblings, 0 replies; 30+ messages in thread
From: James Hogan @ 2017-07-18 11:55 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: qemu-devel, James Hogan, Aurelien Jarno

Add the Enhanced Virtual Addressing (EVA) feature to the P5600 core
configuration, along with the related Segmentation Control (SC) feature
and writable CP0_EBase.WG bit.

This allows it to run Malta EVA kernels.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Reviewed-by: Yongbok Kim <yongbok.kim@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
---
Changes in v2:
- Rename CP0_EBase_rw_bitmask to CP0_EBaseWG_rw_bitmask (Yongbok).
---
 target/mips/translate_init.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/target/mips/translate_init.c b/target/mips/translate_init.c
index 8f8196ed5a6d..741b39023744 100644
--- a/target/mips/translate_init.c
+++ b/target/mips/translate_init.c
@@ -421,9 +421,9 @@ static const mips_def_t mips_defs[] =
     },
     {
         /* FIXME:
-         * Config3: CMGCR, SC, PW, VZ, CTXTC, CDMM, TL
+         * Config3: CMGCR, PW, VZ, CTXTC, CDMM, TL
          * Config4: MMUExtDef
-         * Config5: EVA, MRP
+         * Config5: MRP
          * FIR(FCR0): Has2008
          * */
         .name = "P5600",
@@ -436,13 +436,14 @@ static const mips_def_t mips_defs[] =
                        (1 << CP0C1_PC) | (1 << CP0C1_FP),
         .CP0_Config2 = MIPS_CONFIG2,
         .CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | (1 << CP0C3_MSAP) |
-                       (1 << CP0C3_BP) | (1 << CP0C3_BI) | (1 << CP0C3_ULRI) |
-                       (1 << CP0C3_RXI) | (1 << CP0C3_LPA) | (1 << CP0C3_VInt),
+                       (1 << CP0C3_BP) | (1 << CP0C3_BI) | (1 << CP0C3_SC) |
+                       (1 << CP0C3_ULRI) | (1 << CP0C3_RXI) | (1 << CP0C3_LPA) |
+                       (1 << CP0C3_VInt),
         .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) | (2 << CP0C4_IE) |
                        (0x1c << CP0C4_KScrExist),
         .CP0_Config4_rw_bitmask = 0,
-        .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_MVH) | (1 << CP0C5_LLB) |
-                       (1 << CP0C5_MRP),
+        .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_EVA) | (1 << CP0C5_MVH) |
+                       (1 << CP0C5_LLB) | (1 << CP0C5_MRP),
         .CP0_Config5_rw_bitmask = (1 << CP0C5_K) | (1 << CP0C5_CV) |
                                   (1 << CP0C5_MSAEn) | (1 << CP0C5_UFE) |
                                   (1 << CP0C5_FRE) | (1 << CP0C5_UFR),
@@ -453,6 +454,7 @@ static const mips_def_t mips_defs[] =
         .CP0_Status_rw_bitmask = 0x3C68FF1F,
         .CP0_PageGrain_rw_bitmask = (1U << CP0PG_RIE) | (1 << CP0PG_XIE) |
                     (1 << CP0PG_ELPA) | (1 << CP0PG_IEC),
+        .CP0_EBaseWG_rw_bitmask = (1 << CP0EBase_WG),
         .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_UFRP) | (1 << FCR0_HAS2008) |
                     (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
                     (1 << FCR0_D) | (1 << FCR0_S) | (0x03 << FCR0_PRID),
-- 
git-series 0.8.10

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH 14/14] target/mips: Enable CP0_EBase.WG on MIPS64 CPUs
  2017-07-18 11:55 [Qemu-devel] [PATCH 0/14] target/mips: Add Enhanced Virtual Addressing (EVA) support James Hogan
                   ` (12 preceding siblings ...)
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 13/14] target/mips: Add EVA support to P5600 James Hogan
@ 2017-07-18 11:55 ` James Hogan
  2017-07-20 13:12   ` Yongbok Kim
  2017-07-18 21:21 ` [Qemu-devel] [PATCH 0/14] target/mips: Add Enhanced Virtual Addressing (EVA) support no-reply
  14 siblings, 1 reply; 30+ messages in thread
From: James Hogan @ 2017-07-18 11:55 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: qemu-devel, James Hogan, Aurelien Jarno

Enable the CP0_EBase.WG (write gate) on the I6400 and MIPS64R2-generic
CPUs. This allows 64-bit guests to run KVM itself, which uses
CP0_EBase.WG to point CP0_EBase at XKPhys.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Yongbok Kim <yongbok.kim@imgtec.com>
Cc: Aurelien Jarno <aurelien@aurel32.net>
---
Changes in v2:
- New patch.
---
 target/mips/translate_init.c | 2 ++
 1 file changed, 2 insertions(+), 0 deletions(-)

diff --git a/target/mips/translate_init.c b/target/mips/translate_init.c
index 741b39023744..255d25bacd03 100644
--- a/target/mips/translate_init.c
+++ b/target/mips/translate_init.c
@@ -640,6 +640,7 @@ static const mips_def_t mips_defs[] =
         .SYNCI_Step = 32,
         .CCRes = 2,
         .CP0_Status_rw_bitmask = 0x36FBFFFF,
+        .CP0_EBaseWG_rw_bitmask = (1 << CP0EBase_WG),
         .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_3D) | (1 << FCR0_PS) |
                     (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) |
                     (1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV),
@@ -723,6 +724,7 @@ static const mips_def_t mips_defs[] =
         .CP0_PageGrain = (1 << CP0PG_IEC) | (1 << CP0PG_XIE) |
                          (1U << CP0PG_RIE),
         .CP0_PageGrain_rw_bitmask = (1 << CP0PG_ELPA),
+        .CP0_EBaseWG_rw_bitmask = (1 << CP0EBase_WG),
         .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_HAS2008) | (1 << FCR0_F64) |
                     (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) |
                     (1 << FCR0_S) | (0x03 << FCR0_PRID) | (0x0 << FCR0_REV),
-- 
git-series 0.8.10

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH 1/14] target/mips: Fix MIPS64 MFC0 UserLocal on BE host
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 1/14] target/mips: Fix MIPS64 MFC0 UserLocal on BE host James Hogan
@ 2017-07-18 14:37   ` Yongbok Kim
  2017-07-19 10:27   ` Aurelien Jarno
  1 sibling, 0 replies; 30+ messages in thread
From: Yongbok Kim @ 2017-07-18 14:37 UTC (permalink / raw)
  To: James Hogan; +Cc: qemu-devel, Aurelien Jarno, Petar Jovanovic



On 18/07/2017 12:55, James Hogan wrote:
> Using MFC0 to read CP0_UserLocal uses tcg_gen_ld32s_tl, however
> CP0_UserLocal is a target_ulong. On a big endian host with a MIPS64
> target this reads and sign extends the more significant half of the
> 64-bit register.
> 
> Fix this by using ld_tl to load the whole target_ulong and ext32s_tl to
> sign extend it, as done for various other target_ulong COP0 registers.
> 
> Fixes: d279279e2b5c ("target-mips: implement UserLocal Register")
> Signed-off-by: James Hogan <james.hogan@imgtec.com>
> Cc: Yongbok Kim <yongbok.kim@imgtec.com>
> Cc: Aurelien Jarno <aurelien@aurel32.net>
> Cc: Petar Jovanovic <petar.jovanovic@imgtec.com>
> ---
> Changes in v2:
> - New patch.
> ---
>  target/mips/translate.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/target/mips/translate.c b/target/mips/translate.c
> index 3022f349cb2a..556aba969a12 100644
> --- a/target/mips/translate.c
> +++ b/target/mips/translate.c
> @@ -5138,8 +5138,9 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
>              goto cp0_unimplemented;
>          case 2:
>              CP0_CHECK(ctx->ulri);
> -            tcg_gen_ld32s_tl(arg, cpu_env,
> -                             offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
> +            tcg_gen_ld_tl(arg, cpu_env,
> +                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
> +            tcg_gen_ext32s_tl(arg, arg);
>              rn = "UserLocal";
>              break;
>          default:
> 

Reviewed-by: Yongbok Kim <yongbok.kim@imgtec.com>

Regards,
Yongbok

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH 6/14] target/mips: Decode MIPS32 EVA load & store instructions
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 6/14] target/mips: Decode MIPS32 EVA load & store instructions James Hogan
@ 2017-07-18 15:43   ` Yongbok Kim
  0 siblings, 0 replies; 30+ messages in thread
From: Yongbok Kim @ 2017-07-18 15:43 UTC (permalink / raw)
  To: James Hogan; +Cc: qemu-devel, Aurelien Jarno



On 18/07/2017 12:55, James Hogan wrote:
> Implement decoding of MIPS32 EVA loads and stores. These access the user
> address space from kernel mode when implemented, so for each instruction
> we need to check that EVA is available from Config5.EVA & check for
> sufficient COP0 privilege (with the new check_eva()), and then override
> the mem_idx used for the operation.
> 
> Unfortunately some Loongson 2E instructions use overlapping encodings,
> so we must be careful not to prevent those from being decoded when EVA
> is absent.
> 
> Signed-off-by: James Hogan <james.hogan@imgtec.com>
> Cc: Yongbok Kim <yongbok.kim@imgtec.com>
> Cc: Aurelien Jarno <aurelien@aurel32.net>
> ---
> Changes in v2:
> - Fix typo in commit message (Yongbok).
> - Use sextract32 (Yongbok).
> ---
>  target/mips/translate.c | 106 +++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 106 insertions(+), 0 deletions(-)
> 

Reviewed-by: Yongbok Kim <yongbok.kim@imgtec.com>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH 7/14] target/mips: Decode microMIPS EVA load & store instructions
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 7/14] target/mips: Decode microMIPS " James Hogan
@ 2017-07-18 16:07   ` Yongbok Kim
  0 siblings, 0 replies; 30+ messages in thread
From: Yongbok Kim @ 2017-07-18 16:07 UTC (permalink / raw)
  To: James Hogan; +Cc: qemu-devel, Aurelien Jarno



On 18/07/2017 12:55, James Hogan wrote:
> Implement decoding of microMIPS EVA load and store instruction groups in
> the POOL31C pool. These use the same gen_ld(), gen_st(), gen_st_cond()
> helpers as the MIPS32 decoding, passing the equivalent MIPS32 opcodes as
> opc.
> 
> Signed-off-by: James Hogan <james.hogan@imgtec.com>
> Cc: Yongbok Kim <yongbok.kim@imgtec.com>
> Cc: Aurelien Jarno <aurelien@aurel32.net>
> ---
> Changes in v2:
> - New patch (Yongbok).
> ---
>  target/mips/translate.c | 119 +++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 115 insertions(+), 4 deletions(-)
> 

Reviewed-by: Yongbok Kim <yongbok.kim@imgtec.com>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH 0/14] target/mips: Add Enhanced Virtual Addressing (EVA) support
  2017-07-18 11:55 [Qemu-devel] [PATCH 0/14] target/mips: Add Enhanced Virtual Addressing (EVA) support James Hogan
                   ` (13 preceding siblings ...)
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 14/14] target/mips: Enable CP0_EBase.WG on MIPS64 CPUs James Hogan
@ 2017-07-18 21:21 ` no-reply
  2017-07-19  9:02   ` James Hogan
  14 siblings, 1 reply; 30+ messages in thread
From: no-reply @ 2017-07-18 21:21 UTC (permalink / raw)
  To: james.hogan; +Cc: famz, yongbok.kim, qemu-devel, aurelien, petar.jovanovic

Hi,

This series seems to have some coding style problems. See output below for
more information:

Subject: [Qemu-devel] [PATCH 0/14] target/mips: Add Enhanced Virtual Addressing (EVA) support
Message-id: cover.34f8428dbbcaa0611cef759667d281ae508ac91d.1500378931.git-series.james.hogan@imgtec.com
Type: series

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
888a8b3 target/mips: Enable CP0_EBase.WG on MIPS64 CPUs
ff13d16 target/mips: Add EVA support to P5600
3edc7b0 target/mips: Implement segmentation control
796fdf5 target/mips: Add segmentation control registers
f72fe25 target/mips: Add an MMU mode for ERL
0bcefc0 target/mips: Abstract mmu_idx from hflags
39dc7d8 target/mips: Check memory permissions with mem_idx
d75cb8a target/mips: Decode microMIPS EVA load & store instructions
d92ac8c target/mips: Decode MIPS32 EVA load & store instructions
4f20958 target/mips: Prepare loads/stores for EVA
b99a507 target/mips: Add CP0_Ebase.WG (write gate) support
97df4ad target/mips: Weaken TLB flush on UX, SX, KX, ASID changes
4c8f539 target/mips: Fix TLBWI shadow flush for EHINV, XI, RI
57afc02 target/mips: Fix MIPS64 MFC0 UserLocal on BE host

=== OUTPUT BEGIN ===
Checking PATCH 1/14: target/mips: Fix MIPS64 MFC0 UserLocal on BE host...
Checking PATCH 2/14: target/mips: Fix TLBWI shadow flush for EHINV, XI, RI...
ERROR: space prohibited after that '&' (ctx:WxW)
#44: FILE: target/mips/op_helper.c:2045:
+    XI0 = (env->CP0_EntryLo0 >> CP0EnLo_XI) & 1;
                                             ^

ERROR: space prohibited after that '&' (ctx:WxW)
#45: FILE: target/mips/op_helper.c:2046:
+    RI0 = (env->CP0_EntryLo0 >> CP0EnLo_RI) & 1;
                                             ^

ERROR: space prohibited after that '&' (ctx:WxW)
#48: FILE: target/mips/op_helper.c:2049:
+    XI1 = (env->CP0_EntryLo1 >> CP0EnLo_XI) & 1;
                                             ^

ERROR: space prohibited after that '&' (ctx:WxW)
#49: FILE: target/mips/op_helper.c:2050:
+    RI1 = (env->CP0_EntryLo1 >> CP0EnLo_RI) & 1;
                                             ^

total: 4 errors, 0 warnings, 34 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 3/14: target/mips: Weaken TLB flush on UX, SX, KX, ASID changes...
Checking PATCH 4/14: target/mips: Add CP0_Ebase.WG (write gate) support...
ERROR: space prohibited after that '&' (ctx:WxW)
#114: FILE: target/mips/op_helper.c:1519:
+    if (arg1 & (1 << CP0EBase_WG) & mask) {
                                   ^

ERROR: space prohibited after that '&' (ctx:WxW)
#126: FILE: target/mips/op_helper.c:1530:
+    if (arg1 & (1 << CP0EBase_WG) & mask) {
                                   ^

total: 2 errors, 0 warnings, 126 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 5/14: target/mips: Prepare loads/stores for EVA...
Checking PATCH 6/14: target/mips: Decode MIPS32 EVA load & store instructions...
Checking PATCH 7/14: target/mips: Decode microMIPS EVA load & store instructions...
Checking PATCH 8/14: target/mips: Check memory permissions with mem_idx...
Checking PATCH 9/14: target/mips: Abstract mmu_idx from hflags...
Checking PATCH 10/14: target/mips: Add an MMU mode for ERL...
ERROR: trailing statements should be on next line
#94: FILE: target/mips/op_helper.c:98:
+    case 3: cpu_##insn##_error_ra(env, addr, val, retaddr); break;      \

ERROR: trailing statements should be on next line
#102: FILE: target/mips/op_helper.c:1456:
+        case 3: qemu_log(", ERL\n"); break;

ERROR: trailing statements should be on next line
#110: FILE: target/mips/op_helper.c:2251:
+        case 3: qemu_log(", ERL\n"); break;

total: 3 errors, 0 warnings, 79 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 11/14: target/mips: Add segmentation control registers...
Checking PATCH 12/14: target/mips: Implement segmentation control...
ERROR: braces {} are necessary for all arms of this statement
#246: FILE: target/mips/helper.c:836:
+            if ((R != 0 || UX) && (R != 3 || KX) &&
[...]

ERROR: braces {} are necessary for all arms of this statement
#258: FILE: target/mips/helper.c:854:
+            if ((R != 0 || UX) && (R != 3 || KX) &&
[...]

total: 2 errors, 0 warnings, 234 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 13/14: target/mips: Add EVA support to P5600...
Checking PATCH 14/14: target/mips: Enable CP0_EBase.WG on MIPS64 CPUs...
=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH 11/14] target/mips: Add segmentation control registers
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 11/14] target/mips: Add segmentation control registers James Hogan
@ 2017-07-18 22:01   ` Yongbok Kim
  0 siblings, 0 replies; 30+ messages in thread
From: Yongbok Kim @ 2017-07-18 22:01 UTC (permalink / raw)
  To: James Hogan; +Cc: qemu-devel, Aurelien Jarno



On 18/07/2017 12:55, James Hogan wrote:
> The optional segmentation control registers CP0_SegCtl0, CP0_SegCtl1 &
> CP0_SegCtl2 control the behaviour and required privilege of the legacy
> virtual memory segments.
> 
> Add them to the CP0 interface so they can be read and written when
> CP0_Config3.SC=1, and initialise them to describe the standard legacy
> layout so they can be used in future patches regardless of whether they
> are exposed to the guest.
> 
> Signed-off-by: James Hogan <james.hogan@imgtec.com>
> Cc: Yongbok Kim <yongbok.kim@imgtec.com>
> Cc: Aurelien Jarno <aurelien@aurel32.net>
> ---
> Changes in v2:
> - Use ld_tl and ext32s_tl rather than ld32s_tl to avoid big endian host,
>   MIPS64 target issues (Yongbok).
> - Add missing break in DMFC0 CP0_SegCtl2 case.
> ---
>  target/mips/cpu.h       | 30 ++++++++++++++-
>  target/mips/helper.h    |  3 +-
>  target/mips/machine.c   |  7 ++-
>  target/mips/op_helper.c | 24 +++++++++++-
>  target/mips/translate.c | 88 ++++++++++++++++++++++++++++++++++++++++++-
>  5 files changed, 150 insertions(+), 2 deletions(-)
> 


Reviewed-by: Yongbok Kim <yongbok.kim@imgtec.com>

Regards,
Yongbok

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH 0/14] target/mips: Add Enhanced Virtual Addressing (EVA) support
  2017-07-18 21:21 ` [Qemu-devel] [PATCH 0/14] target/mips: Add Enhanced Virtual Addressing (EVA) support no-reply
@ 2017-07-19  9:02   ` James Hogan
  0 siblings, 0 replies; 30+ messages in thread
From: James Hogan @ 2017-07-19  9:02 UTC (permalink / raw)
  To: qemu-devel; +Cc: famz, yongbok.kim, aurelien, petar.jovanovic

[-- Attachment #1: Type: text/plain, Size: 2546 bytes --]

On Tue, Jul 18, 2017 at 02:21:20PM -0700, no-reply@patchew.org wrote:
> Checking PATCH 2/14: target/mips: Fix TLBWI shadow flush for EHINV, XI, RI...
> ERROR: space prohibited after that '&' (ctx:WxW)
> #44: FILE: target/mips/op_helper.c:2045:
> +    XI0 = (env->CP0_EntryLo0 >> CP0EnLo_XI) & 1;
>                                              ^
> 
> ERROR: space prohibited after that '&' (ctx:WxW)
> #45: FILE: target/mips/op_helper.c:2046:
> +    RI0 = (env->CP0_EntryLo0 >> CP0EnLo_RI) & 1;
>                                              ^
> 
> ERROR: space prohibited after that '&' (ctx:WxW)
> #48: FILE: target/mips/op_helper.c:2049:
> +    XI1 = (env->CP0_EntryLo1 >> CP0EnLo_XI) & 1;
>                                              ^
> 
> ERROR: space prohibited after that '&' (ctx:WxW)
> #49: FILE: target/mips/op_helper.c:2050:
> +    RI1 = (env->CP0_EntryLo1 >> CP0EnLo_RI) & 1;
>                                              ^
> 
> total: 4 errors, 0 warnings, 34 lines checked

These are false positives. The code looks fine to me. They are binary
bitwise-and operators, not unary address-of operators.

> Your patch has style problems, please review.  If any of these errors
> are false positives report them to the maintainer, see
> CHECKPATCH in MAINTAINERS.

It looks orphaned.

> Checking PATCH 10/14: target/mips: Add an MMU mode for ERL...
> ERROR: trailing statements should be on next line
> #94: FILE: target/mips/op_helper.c:98:
> +    case 3: cpu_##insn##_error_ra(env, addr, val, retaddr); break;      \
> 
> ERROR: trailing statements should be on next line
> #102: FILE: target/mips/op_helper.c:1456:
> +        case 3: qemu_log(", ERL\n"); break;
> 
> ERROR: trailing statements should be on next line
> #110: FILE: target/mips/op_helper.c:2251:
> +        case 3: qemu_log(", ERL\n"); break;
> 
> total: 3 errors, 0 warnings, 79 lines checked

These are all consistent with the surrounding code.

> Checking PATCH 12/14: target/mips: Implement segmentation control...
> ERROR: braces {} are necessary for all arms of this statement
> #246: FILE: target/mips/helper.c:836:
> +            if ((R != 0 || UX) && (R != 3 || KX) &&
> [...]
> 
> ERROR: braces {} are necessary for all arms of this statement
> #258: FILE: target/mips/helper.c:854:
> +            if ((R != 0 || UX) && (R != 3 || KX) &&
> [...]
> 
> total: 2 errors, 0 warnings, 234 lines checked

And these are both pre-existing style issues that the patch hasn't
changed.

Cheers
James

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH 1/14] target/mips: Fix MIPS64 MFC0 UserLocal on BE host
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 1/14] target/mips: Fix MIPS64 MFC0 UserLocal on BE host James Hogan
  2017-07-18 14:37   ` Yongbok Kim
@ 2017-07-19 10:27   ` Aurelien Jarno
  2017-07-19 13:44     ` James Hogan
  1 sibling, 1 reply; 30+ messages in thread
From: Aurelien Jarno @ 2017-07-19 10:27 UTC (permalink / raw)
  To: James Hogan; +Cc: Yongbok Kim, qemu-devel, Petar Jovanovic

On 2017-07-18 12:55, James Hogan wrote:
> Using MFC0 to read CP0_UserLocal uses tcg_gen_ld32s_tl, however
> CP0_UserLocal is a target_ulong. On a big endian host with a MIPS64
> target this reads and sign extends the more significant half of the
> 64-bit register.
> 
> Fix this by using ld_tl to load the whole target_ulong and ext32s_tl to
> sign extend it, as done for various other target_ulong COP0 registers.
> 
> Fixes: d279279e2b5c ("target-mips: implement UserLocal Register")
> Signed-off-by: James Hogan <james.hogan@imgtec.com>
> Cc: Yongbok Kim <yongbok.kim@imgtec.com>
> Cc: Aurelien Jarno <aurelien@aurel32.net>
> Cc: Petar Jovanovic <petar.jovanovic@imgtec.com>
> ---
> Changes in v2:
> - New patch.
> ---
>  target/mips/translate.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/target/mips/translate.c b/target/mips/translate.c
> index 3022f349cb2a..556aba969a12 100644
> --- a/target/mips/translate.c
> +++ b/target/mips/translate.c
> @@ -5138,8 +5138,9 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
>              goto cp0_unimplemented;
>          case 2:
>              CP0_CHECK(ctx->ulri);
> -            tcg_gen_ld32s_tl(arg, cpu_env,
> -                             offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
> +            tcg_gen_ld_tl(arg, cpu_env,
> +                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
> +            tcg_gen_ext32s_tl(arg, arg);
>              rn = "UserLocal";
>              break;
>          default:

I think this is what gen_mfc0_load64() does, that said this whole area
probably need a rework (see for example how inefficiently
gen_mfc0_load32 is implemented). So:

Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>

-- 
Aurelien Jarno                          GPG: 4096R/1DDD8C9B
aurelien@aurel32.net                 http://www.aurel32.net

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH 1/14] target/mips: Fix MIPS64 MFC0 UserLocal on BE host
  2017-07-19 10:27   ` Aurelien Jarno
@ 2017-07-19 13:44     ` James Hogan
  2017-07-19 16:26       ` Aurelien Jarno
  0 siblings, 1 reply; 30+ messages in thread
From: James Hogan @ 2017-07-19 13:44 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: Yongbok Kim, qemu-devel, Petar Jovanovic

[-- Attachment #1: Type: text/plain, Size: 2149 bytes --]

On Wed, Jul 19, 2017 at 12:27:50PM +0200, Aurelien Jarno wrote:
> On 2017-07-18 12:55, James Hogan wrote:
> > Using MFC0 to read CP0_UserLocal uses tcg_gen_ld32s_tl, however
> > CP0_UserLocal is a target_ulong. On a big endian host with a MIPS64
> > target this reads and sign extends the more significant half of the
> > 64-bit register.
> > 
> > Fix this by using ld_tl to load the whole target_ulong and ext32s_tl to
> > sign extend it, as done for various other target_ulong COP0 registers.
> > 
> > Fixes: d279279e2b5c ("target-mips: implement UserLocal Register")
> > Signed-off-by: James Hogan <james.hogan@imgtec.com>
> > Cc: Yongbok Kim <yongbok.kim@imgtec.com>
> > Cc: Aurelien Jarno <aurelien@aurel32.net>
> > Cc: Petar Jovanovic <petar.jovanovic@imgtec.com>
> > ---
> > Changes in v2:
> > - New patch.
> > ---
> >  target/mips/translate.c | 5 +++--
> >  1 file changed, 3 insertions(+), 2 deletions(-)
> > 
> > diff --git a/target/mips/translate.c b/target/mips/translate.c
> > index 3022f349cb2a..556aba969a12 100644
> > --- a/target/mips/translate.c
> > +++ b/target/mips/translate.c
> > @@ -5138,8 +5138,9 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> >              goto cp0_unimplemented;
> >          case 2:
> >              CP0_CHECK(ctx->ulri);
> > -            tcg_gen_ld32s_tl(arg, cpu_env,
> > -                             offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
> > +            tcg_gen_ld_tl(arg, cpu_env,
> > +                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
> > +            tcg_gen_ext32s_tl(arg, arg);
> >              rn = "UserLocal";
> >              break;
> >          default:
> 
> I think this is what gen_mfc0_load64() does, that said this whole area

Ah yes, that could do with some wider use (and possibly s/64/tl/ or
something).

> probably need a rework (see for example how inefficiently
> gen_mfc0_load32 is implemented). So:

Erm, doesn't gen_mfc0_load32() fail to sign extend as it should when
used for mfc0...?

> 
> Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>

Cheers
James

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH 4/14] target/mips: Add CP0_Ebase.WG (write gate) support
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 4/14] target/mips: Add CP0_Ebase.WG (write gate) support James Hogan
@ 2017-07-19 14:54   ` Yongbok Kim
  2017-07-19 15:02     ` James Hogan
  0 siblings, 1 reply; 30+ messages in thread
From: Yongbok Kim @ 2017-07-19 14:54 UTC (permalink / raw)
  To: James Hogan; +Cc: qemu-devel, Aurelien Jarno



On 18/07/2017 12:55, James Hogan wrote:
> Add support for the CP0_EBase.WG bit, which allows upper bits to be
> written (bits 31:30 on MIPS32, or bits 63:30 on MIPS64), along with the
> CP0_Config5.CV bit to control whether the exception vector for Cache
> Error exceptions is forced into KSeg1.
> 
> This is necessary on MIPS32 to support Segmentation Control and Enhanced
> Virtual Addressing (EVA) extensions (where KSeg1 addresses may not
> represent an unmapped uncached segment).
> 
> It is also useful on MIPS64 to allow the exception base to reside in
> XKPhys, and possibly out of range of KSEG0 and KSEG1.
> 
> Signed-off-by: James Hogan <james.hogan@imgtec.com>
> Cc: Yongbok Kim <yongbok.kim@imgtec.com>
> Cc: Aurelien Jarno <aurelien@aurel32.net>
> ---
> Changes in v2:
> - Fix CP0_EBase.WG to be read only when WG is not set in
>   CP0_EBase_rw_bitmask, otherwise it will be wrongly probed as present.
> - Make cache error exception vector conditional on Config3.SC as well as
>   Config5.CV, as per the PRA, and take the CP0C3_SC definition from
>   patch 7 (Yongbok).
> - Rename CP0_EBase_rw_bitmask to CP0_EBaseWG_rw_bitmask (Yongbok).
> ---
>  target/mips/cpu.h            |  5 ++++-
>  target/mips/helper.c         | 14 ++++++++------
>  target/mips/machine.c        |  6 +++---
>  target/mips/op_helper.c      | 12 ++++++++++--
>  target/mips/translate.c      |  8 +++++---
>  target/mips/translate_init.c |  1 +
>  6 files changed, 31 insertions(+), 15 deletions(-)
> 


> --- a/target/mips/op_helper.c
> +++ b/target/mips/op_helper.c
> @@ -1515,14 +1515,22 @@ target_ulong helper_mftc0_ebase(CPUMIPSState *env)
>  
>  void helper_mtc0_ebase(CPUMIPSState *env, target_ulong arg1)
>  {
> -    env->CP0_EBase = (env->CP0_EBase & ~0x3FFFF000) | (arg1 & 0x3FFFF000);
> +    target_ulong mask = 0x3FFFF000 | env->CP0_EBaseWG_rw_bitmask;
> +    if (arg1 & (1 << CP0EBase_WG) & mask) {

isn't it just ...?
if (arg1 & env->CP0_EBaseWG_rw_bitmask) {

> +        mask |= ~0x3FFFFFFF;
> +    }
> +    env->CP0_EBase = (env->CP0_EBase & ~mask) | (arg1 & mask);
>  }
>  
>  void helper_mttc0_ebase(CPUMIPSState *env, target_ulong arg1)
>  {
>      int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
>      CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
> -    other->CP0_EBase = (other->CP0_EBase & ~0x3FFFF000) | (arg1 & 0x3FFFF000);
> +    target_ulong mask = 0x3FFFF000 | env->CP0_EBaseWG_rw_bitmask;
> +    if (arg1 & (1 << CP0EBase_WG) & mask) {

here as well.

> +        mask |= ~0x3FFFFFFF;
> +    }
> +    other->CP0_EBase = (other->CP0_EBase & ~mask) | (arg1 & mask);
>  }
>  


Otherwise,
Reviewed-by: Yongbok Kim <yongbok.kim@imgtec.com>

Regards,
Yongbok

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH 4/14] target/mips: Add CP0_Ebase.WG (write gate) support
  2017-07-19 14:54   ` Yongbok Kim
@ 2017-07-19 15:02     ` James Hogan
  0 siblings, 0 replies; 30+ messages in thread
From: James Hogan @ 2017-07-19 15:02 UTC (permalink / raw)
  To: Yongbok Kim; +Cc: qemu-devel, Aurelien Jarno

[-- Attachment #1: Type: text/plain, Size: 3071 bytes --]

On Wed, Jul 19, 2017 at 03:54:47PM +0100, Yongbok Kim wrote:
> 
> 
> On 18/07/2017 12:55, James Hogan wrote:
> > Add support for the CP0_EBase.WG bit, which allows upper bits to be
> > written (bits 31:30 on MIPS32, or bits 63:30 on MIPS64), along with the
> > CP0_Config5.CV bit to control whether the exception vector for Cache
> > Error exceptions is forced into KSeg1.
> > 
> > This is necessary on MIPS32 to support Segmentation Control and Enhanced
> > Virtual Addressing (EVA) extensions (where KSeg1 addresses may not
> > represent an unmapped uncached segment).
> > 
> > It is also useful on MIPS64 to allow the exception base to reside in
> > XKPhys, and possibly out of range of KSEG0 and KSEG1.
> > 
> > Signed-off-by: James Hogan <james.hogan@imgtec.com>
> > Cc: Yongbok Kim <yongbok.kim@imgtec.com>
> > Cc: Aurelien Jarno <aurelien@aurel32.net>
> > ---
> > Changes in v2:
> > - Fix CP0_EBase.WG to be read only when WG is not set in
> >   CP0_EBase_rw_bitmask, otherwise it will be wrongly probed as present.
> > - Make cache error exception vector conditional on Config3.SC as well as
> >   Config5.CV, as per the PRA, and take the CP0C3_SC definition from
> >   patch 7 (Yongbok).
> > - Rename CP0_EBase_rw_bitmask to CP0_EBaseWG_rw_bitmask (Yongbok).
> > ---
> >  target/mips/cpu.h            |  5 ++++-
> >  target/mips/helper.c         | 14 ++++++++------
> >  target/mips/machine.c        |  6 +++---
> >  target/mips/op_helper.c      | 12 ++++++++++--
> >  target/mips/translate.c      |  8 +++++---
> >  target/mips/translate_init.c |  1 +
> >  6 files changed, 31 insertions(+), 15 deletions(-)
> > 
> 
> 
> > --- a/target/mips/op_helper.c
> > +++ b/target/mips/op_helper.c
> > @@ -1515,14 +1515,22 @@ target_ulong helper_mftc0_ebase(CPUMIPSState *env)
> >  
> >  void helper_mtc0_ebase(CPUMIPSState *env, target_ulong arg1)
> >  {
> > -    env->CP0_EBase = (env->CP0_EBase & ~0x3FFFF000) | (arg1 & 0x3FFFF000);
> > +    target_ulong mask = 0x3FFFF000 | env->CP0_EBaseWG_rw_bitmask;
> > +    if (arg1 & (1 << CP0EBase_WG) & mask) {
> 
> isn't it just ...?
> if (arg1 & env->CP0_EBaseWG_rw_bitmask) {

I suppose, now that the field is specific to the WG bit.

Thanks
James

> 
> > +        mask |= ~0x3FFFFFFF;
> > +    }
> > +    env->CP0_EBase = (env->CP0_EBase & ~mask) | (arg1 & mask);
> >  }
> >  
> >  void helper_mttc0_ebase(CPUMIPSState *env, target_ulong arg1)
> >  {
> >      int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
> >      CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
> > -    other->CP0_EBase = (other->CP0_EBase & ~0x3FFFF000) | (arg1 & 0x3FFFF000);
> > +    target_ulong mask = 0x3FFFF000 | env->CP0_EBaseWG_rw_bitmask;
> > +    if (arg1 & (1 << CP0EBase_WG) & mask) {
> 
> here as well.
> 
> > +        mask |= ~0x3FFFFFFF;
> > +    }
> > +    other->CP0_EBase = (other->CP0_EBase & ~mask) | (arg1 & mask);
> >  }
> >  
> 
> 
> Otherwise,
> Reviewed-by: Yongbok Kim <yongbok.kim@imgtec.com>
> 
> Regards,
> Yongbok

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH 1/14] target/mips: Fix MIPS64 MFC0 UserLocal on BE host
  2017-07-19 13:44     ` James Hogan
@ 2017-07-19 16:26       ` Aurelien Jarno
  0 siblings, 0 replies; 30+ messages in thread
From: Aurelien Jarno @ 2017-07-19 16:26 UTC (permalink / raw)
  To: James Hogan; +Cc: Yongbok Kim, qemu-devel, Petar Jovanovic

[-- Attachment #1: Type: text/plain, Size: 2593 bytes --]

On 2017-07-19 14:44, James Hogan wrote:
> On Wed, Jul 19, 2017 at 12:27:50PM +0200, Aurelien Jarno wrote:
> > On 2017-07-18 12:55, James Hogan wrote:
> > > Using MFC0 to read CP0_UserLocal uses tcg_gen_ld32s_tl, however
> > > CP0_UserLocal is a target_ulong. On a big endian host with a MIPS64
> > > target this reads and sign extends the more significant half of the
> > > 64-bit register.
> > > 
> > > Fix this by using ld_tl to load the whole target_ulong and ext32s_tl to
> > > sign extend it, as done for various other target_ulong COP0 registers.
> > > 
> > > Fixes: d279279e2b5c ("target-mips: implement UserLocal Register")
> > > Signed-off-by: James Hogan <james.hogan@imgtec.com>
> > > Cc: Yongbok Kim <yongbok.kim@imgtec.com>
> > > Cc: Aurelien Jarno <aurelien@aurel32.net>
> > > Cc: Petar Jovanovic <petar.jovanovic@imgtec.com>
> > > ---
> > > Changes in v2:
> > > - New patch.
> > > ---
> > >  target/mips/translate.c | 5 +++--
> > >  1 file changed, 3 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/target/mips/translate.c b/target/mips/translate.c
> > > index 3022f349cb2a..556aba969a12 100644
> > > --- a/target/mips/translate.c
> > > +++ b/target/mips/translate.c
> > > @@ -5138,8 +5138,9 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
> > >              goto cp0_unimplemented;
> > >          case 2:
> > >              CP0_CHECK(ctx->ulri);
> > > -            tcg_gen_ld32s_tl(arg, cpu_env,
> > > -                             offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
> > > +            tcg_gen_ld_tl(arg, cpu_env,
> > > +                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
> > > +            tcg_gen_ext32s_tl(arg, arg);
> > >              rn = "UserLocal";
> > >              break;
> > >          default:
> > 
> > I think this is what gen_mfc0_load64() does, that said this whole area
> 
> Ah yes, that could do with some wider use (and possibly s/64/tl/ or
> something).
> 
> > probably need a rework (see for example how inefficiently
> > gen_mfc0_load32 is implemented). So:
> 
> Erm, doesn't gen_mfc0_load32() fail to sign extend as it should when
> used for mfc0...?

Yes, this is correct. tcg_gen_ext_i32_tl sign-extends the value when
converting it from TCGv_i32 to TCGv_tl. tcg_gen_extu_i32_tl is the op
which zero-extends the value. Basically TCG sign-extends the value "by
default", like for MIPS.

Aurelien

-- 
Aurelien Jarno                          GPG: 4096R/1DDD8C9B
aurelien@aurel32.net                 http://www.aurel32.net

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH 12/14] target/mips: Implement segmentation control
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 12/14] target/mips: Implement segmentation control James Hogan
@ 2017-07-20 13:08   ` Yongbok Kim
  0 siblings, 0 replies; 30+ messages in thread
From: Yongbok Kim @ 2017-07-20 13:08 UTC (permalink / raw)
  To: James Hogan; +Cc: qemu-devel, Aurelien Jarno



On 18/07/2017 12:55, James Hogan wrote:
> Implement the optional segmentation control feature in the virtual to
> physical address translation code.
> 
> The fixed legacy segment and xkphys handling is replaced with a dynamic
> layout based on the segmentation control registers (which should be set
> up even when the feature is not exposed to the guest).
> 
> Signed-off-by: James Hogan <james.hogan@imgtec.com>
> Cc: Yongbok Kim <yongbok.kim@imgtec.com>
> Cc: Aurelien Jarno <aurelien@aurel32.net>
> ---
> Changes in v2:
> - Use hwaddr instead of target_ulong for physical addresses in
>   get_seg[ctl]_physical_address() (Yongbok).
> - Fix xkphys privilege control based on access mode (am) (Yongbok).
> - Fix xkphys TLB faults to use XTLB.
> ---
>  target/mips/helper.c | 177 +++++++++++++++++++++++++++++++++++---------
>  1 file changed, 142 insertions(+), 35 deletions(-)
> 

Reviewed-by: Yongbok Kim <yongbok.kim@imgtec.com>

Regards,
Yongbok

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH 14/14] target/mips: Enable CP0_EBase.WG on MIPS64 CPUs
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 14/14] target/mips: Enable CP0_EBase.WG on MIPS64 CPUs James Hogan
@ 2017-07-20 13:12   ` Yongbok Kim
  0 siblings, 0 replies; 30+ messages in thread
From: Yongbok Kim @ 2017-07-20 13:12 UTC (permalink / raw)
  To: James Hogan; +Cc: qemu-devel, Aurelien Jarno



On 18/07/2017 12:55, James Hogan wrote:
> Enable the CP0_EBase.WG (write gate) on the I6400 and MIPS64R2-generic
> CPUs. This allows 64-bit guests to run KVM itself, which uses
> CP0_EBase.WG to point CP0_EBase at XKPhys.
> 
> Signed-off-by: James Hogan <james.hogan@imgtec.com>
> Cc: Yongbok Kim <yongbok.kim@imgtec.com>
> Cc: Aurelien Jarno <aurelien@aurel32.net>
> ---
> Changes in v2:
> - New patch.
> ---
>  target/mips/translate_init.c | 2 ++
>  1 file changed, 2 insertions(+), 0 deletions(-)
> 
> diff --git a/target/mips/translate_init.c b/target/mips/translate_init.c
> index 741b39023744..255d25bacd03 100644
> --- a/target/mips/translate_init.c
> +++ b/target/mips/translate_init.c
> @@ -640,6 +640,7 @@ static const mips_def_t mips_defs[] =
>          .SYNCI_Step = 32,
>          .CCRes = 2,
>          .CP0_Status_rw_bitmask = 0x36FBFFFF,
> +        .CP0_EBaseWG_rw_bitmask = (1 << CP0EBase_WG),
>          .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_3D) | (1 << FCR0_PS) |
>                      (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) |
>                      (1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV),
> @@ -723,6 +724,7 @@ static const mips_def_t mips_defs[] =
>          .CP0_PageGrain = (1 << CP0PG_IEC) | (1 << CP0PG_XIE) |
>                           (1U << CP0PG_RIE),
>          .CP0_PageGrain_rw_bitmask = (1 << CP0PG_ELPA),
> +        .CP0_EBaseWG_rw_bitmask = (1 << CP0EBase_WG),
>          .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_HAS2008) | (1 << FCR0_F64) |
>                      (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) |
>                      (1 << FCR0_S) | (0x03 << FCR0_PRID) | (0x0 << FCR0_REV),
> 

Reviewed-by: Yongbok Kim <yongbok.kim@imgtec.com>

Regards,
Yongbok

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH 2/14] target/mips: Fix TLBWI shadow flush for EHINV, XI, RI
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 2/14] target/mips: Fix TLBWI shadow flush for EHINV, XI, RI James Hogan
@ 2017-07-20 15:16   ` Yongbok Kim
  0 siblings, 0 replies; 30+ messages in thread
From: Yongbok Kim @ 2017-07-20 15:16 UTC (permalink / raw)
  To: James Hogan; +Cc: qemu-devel, Aurelien Jarno



On 18/07/2017 12:55, James Hogan wrote:
> Writing specific TLB entries with TLBWI flushes shadow TLB entries
> unless an existing entry is having its access permissions upgraded. This
> is necessary as software would from then on expect the previous mapping
> in that entry to no longer be in effect (even if QEMU has quietly
> evicted it to the shadow TLB on a TLBWR).
> 
> However it won't do this if only EHINV, XI, or RI bits have been set,
> even if that results in a reduction of permissions, so add the necessary
> checks to invoke the flush when these bits are set.
> 
> Fixes: 2fb58b73746e ("target-mips: add RI and XI fields to TLB entry")
> Fixes: 9456c2fbcd82 ("target-mips: add TLBINV support")
> Signed-off-by: James Hogan <james.hogan@imgtec.com>
> Cc: Yongbok Kim <yongbok.kim@imgtec.com>
> Cc: Aurelien Jarno <aurelien@aurel32.net>
> ---
> Changes in v2:
> - New patch.
> ---
>  target/mips/op_helper.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
> index e5f3ea40420e..1961cacfab18 100644
> --- a/target/mips/op_helper.c
> +++ b/target/mips/op_helper.c
> @@ -2029,7 +2029,7 @@ void r4k_helper_tlbwi(CPUMIPSState *env)
>      int idx;
>      target_ulong VPN;
>      uint16_t ASID;
> -    bool G, V0, D0, V1, D1;
> +    bool EHINV, G, V0, D0, V1, D1, XI0, XI1, RI0, RI1;
>  
>      idx = (env->CP0_Index & ~0x80000000) % env->tlb->nb_tlb;
>      tlb = &env->tlb->mmu.r4k.tlb[idx];
> @@ -2038,17 +2038,25 @@ void r4k_helper_tlbwi(CPUMIPSState *env)
>      VPN &= env->SEGMask;
>  #endif
>      ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;
> +    EHINV = (env->CP0_EntryHi & (1 << CP0EnHi_EHINV)) != 0;
>      G = env->CP0_EntryLo0 & env->CP0_EntryLo1 & 1;
>      V0 = (env->CP0_EntryLo0 & 2) != 0;
>      D0 = (env->CP0_EntryLo0 & 4) != 0;
> +    XI0 = (env->CP0_EntryLo0 >> CP0EnLo_XI) & 1;
> +    RI0 = (env->CP0_EntryLo0 >> CP0EnLo_RI) & 1;
>      V1 = (env->CP0_EntryLo1 & 2) != 0;
>      D1 = (env->CP0_EntryLo1 & 4) != 0;
> +    XI1 = (env->CP0_EntryLo1 >> CP0EnLo_XI) & 1;
> +    RI1 = (env->CP0_EntryLo1 >> CP0EnLo_RI) & 1;
>  
>      /* Discard cached TLB entries, unless tlbwi is just upgrading access
>         permissions on the current entry. */
>      if (tlb->VPN != VPN || tlb->ASID != ASID || tlb->G != G ||
> +        (!tlb->EHINV && EHINV) ||
>          (tlb->V0 && !V0) || (tlb->D0 && !D0) ||
> -        (tlb->V1 && !V1) || (tlb->D1 && !D1)) {
> +        (!tlb->XI0 && XI0) || (!tlb->RI0 && RI0) ||
> +        (tlb->V1 && !V1) || (tlb->D1 && !D1) ||
> +        (!tlb->XI1 && XI1) || (!tlb->RI1 && RI1)) {
>          r4k_mips_tlb_flush_extra(env, env->tlb->nb_tlb);
>      }
>  
> 

Tested-by: Yongbok Kim <yongbok.kim@imgtec.com>

Regards,
Yongbok

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH 3/14] target/mips: Weaken TLB flush on UX, SX, KX, ASID changes
  2017-07-18 11:55 ` [Qemu-devel] [PATCH 3/14] target/mips: Weaken TLB flush on UX, SX, KX, ASID changes James Hogan
@ 2017-07-20 15:17   ` Yongbok Kim
  0 siblings, 0 replies; 30+ messages in thread
From: Yongbok Kim @ 2017-07-20 15:17 UTC (permalink / raw)
  To: James Hogan; +Cc: qemu-devel, Aurelien Jarno



On 18/07/2017 12:55, James Hogan wrote:
> There is no need to invalidate any shadow TLB entries when the ASID
> changes or when access to one of the 64-bit segments has been disabled,
> since doing so doesn't reveal to software whether any TLB entries have
> been evicted into the shadow half of the TLB.
> 
> Therefore weaken the tlb flushes in these cases to only flush the QEMU
> TLB.
> 
> Signed-off-by: James Hogan <james.hogan@imgtec.com>
> Cc: Yongbok Kim <yongbok.kim@imgtec.com>
> Cc: Aurelien Jarno <aurelien@aurel32.net>
> ---
> Changes in v2:
> - New patch.
> ---
>  target/mips/helper.c    | 2 +-
>  target/mips/op_helper.c | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/target/mips/helper.c b/target/mips/helper.c
> index e359ca3b448d..ceaeb8ceaf49 100644
> --- a/target/mips/helper.c
> +++ b/target/mips/helper.c
> @@ -290,7 +290,7 @@ void cpu_mips_store_status(CPUMIPSState *env, target_ulong val)
>  #if defined(TARGET_MIPS64)
>      if ((env->CP0_Status ^ old) & (old & (7 << CP0St_UX))) {
>          /* Access to at least one of the 64-bit segments has been disabled */
> -        cpu_mips_tlb_flush(env);
> +        tlb_flush(CPU(mips_env_get_cpu(env)));
>      }
>  #endif
>      if (env->CP0_Config3 & (1 << CP0C3_MT)) {
> diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
> index 1961cacfab18..c07f68ce1a97 100644
> --- a/target/mips/op_helper.c
> +++ b/target/mips/op_helper.c
> @@ -1416,7 +1416,7 @@ void helper_mtc0_entryhi(CPUMIPSState *env, target_ulong arg1)
>      /* If the ASID changes, flush qemu's TLB.  */
>      if ((old & env->CP0_EntryHi_ASID_mask) !=
>          (val & env->CP0_EntryHi_ASID_mask)) {
> -        cpu_mips_tlb_flush(env);
> +        tlb_flush(CPU(mips_env_get_cpu(env)));
>      }
>  }
>  
> 

Tested-by: Yongbok Kim <yongbok.kim@imgtec.com>

Regards,
Yongbok

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2017-07-20 15:17 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-07-18 11:55 [Qemu-devel] [PATCH 0/14] target/mips: Add Enhanced Virtual Addressing (EVA) support James Hogan
2017-07-18 11:55 ` [Qemu-devel] [PATCH 1/14] target/mips: Fix MIPS64 MFC0 UserLocal on BE host James Hogan
2017-07-18 14:37   ` Yongbok Kim
2017-07-19 10:27   ` Aurelien Jarno
2017-07-19 13:44     ` James Hogan
2017-07-19 16:26       ` Aurelien Jarno
2017-07-18 11:55 ` [Qemu-devel] [PATCH 2/14] target/mips: Fix TLBWI shadow flush for EHINV, XI, RI James Hogan
2017-07-20 15:16   ` Yongbok Kim
2017-07-18 11:55 ` [Qemu-devel] [PATCH 3/14] target/mips: Weaken TLB flush on UX, SX, KX, ASID changes James Hogan
2017-07-20 15:17   ` Yongbok Kim
2017-07-18 11:55 ` [Qemu-devel] [PATCH 4/14] target/mips: Add CP0_Ebase.WG (write gate) support James Hogan
2017-07-19 14:54   ` Yongbok Kim
2017-07-19 15:02     ` James Hogan
2017-07-18 11:55 ` [Qemu-devel] [PATCH 5/14] target/mips: Prepare loads/stores for EVA James Hogan
2017-07-18 11:55 ` [Qemu-devel] [PATCH 6/14] target/mips: Decode MIPS32 EVA load & store instructions James Hogan
2017-07-18 15:43   ` Yongbok Kim
2017-07-18 11:55 ` [Qemu-devel] [PATCH 7/14] target/mips: Decode microMIPS " James Hogan
2017-07-18 16:07   ` Yongbok Kim
2017-07-18 11:55 ` [Qemu-devel] [PATCH 8/14] target/mips: Check memory permissions with mem_idx James Hogan
2017-07-18 11:55 ` [Qemu-devel] [PATCH 9/14] target/mips: Abstract mmu_idx from hflags James Hogan
2017-07-18 11:55 ` [Qemu-devel] [PATCH 10/14] target/mips: Add an MMU mode for ERL James Hogan
2017-07-18 11:55 ` [Qemu-devel] [PATCH 11/14] target/mips: Add segmentation control registers James Hogan
2017-07-18 22:01   ` Yongbok Kim
2017-07-18 11:55 ` [Qemu-devel] [PATCH 12/14] target/mips: Implement segmentation control James Hogan
2017-07-20 13:08   ` Yongbok Kim
2017-07-18 11:55 ` [Qemu-devel] [PATCH 13/14] target/mips: Add EVA support to P5600 James Hogan
2017-07-18 11:55 ` [Qemu-devel] [PATCH 14/14] target/mips: Enable CP0_EBase.WG on MIPS64 CPUs James Hogan
2017-07-20 13:12   ` Yongbok Kim
2017-07-18 21:21 ` [Qemu-devel] [PATCH 0/14] target/mips: Add Enhanced Virtual Addressing (EVA) support no-reply
2017-07-19  9:02   ` James Hogan

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.