All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 0/7] target-mips: add support for large physical addresses
@ 2015-06-03  9:32 Leon Alrae
  2015-06-03  9:32 ` [Qemu-devel] [PATCH v2 1/7] target-mips: extend selected CP0 registers to 64-bits in MIPS32 Leon Alrae
                   ` (6 more replies)
  0 siblings, 7 replies; 10+ messages in thread
From: Leon Alrae @ 2015-06-03  9:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: james.hogan, aurelien

Hi,

This patchset adds large physical address support in MIPS, specifically:
* eXtended Physical Addressing (XPA)
* Large Physical Addressing (LPA)

XPA and LPA are enabled in MIPS32R5-generic and MIPS64R6-generic cores
respectively.

The series applies on top of the Config5.FRE patches.

Regards,
Leon

v2:
* fix mask used in helper_{d}mtc0_entrylo{0,1} (James)
* remove superfluous brackets (James)
* add missing sign extension in mfhc0 on MIPS64 (this also fixes the issue
  with missing ri/xi masking off)
* take into account CP0_LLAddr_shift (James)
* improve commit message for removing the comments in patch #6 (James)

Leon Alrae (7):
  target-mips: extend selected CP0 registers to 64-bits in MIPS32
  target-mips: support Page Frame Number Extension field
  target-mips: add CP0.PageGrain.ELPA support
  target-mips: add MTHC0 and MFHC0 instructions
  target-mips: correct MFC0 for CP0.EntryLo in MIPS64
  target-mips: remove misleading comments in translate_init.c
  target-mips: enable XPA and LPA features

 disas/mips.c                 |   2 +
 target-mips/cpu.h            |  42 ++++++--
 target-mips/machine.c        |  21 ++--
 target-mips/mips-defs.h      |   4 +-
 target-mips/op_helper.c      |  55 +++++++---
 target-mips/translate.c      | 247 +++++++++++++++++++++++++++++++++++++++++--
 target-mips/translate_init.c |  24 ++---
 7 files changed, 336 insertions(+), 59 deletions(-)

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

* [Qemu-devel] [PATCH v2 1/7] target-mips: extend selected CP0 registers to 64-bits in MIPS32
  2015-06-03  9:32 [Qemu-devel] [PATCH v2 0/7] target-mips: add support for large physical addresses Leon Alrae
@ 2015-06-03  9:32 ` Leon Alrae
  2015-06-04 22:14   ` Aurelien Jarno
  2015-06-03  9:32 ` [Qemu-devel] [PATCH v2 2/7] target-mips: support Page Frame Number Extension field Leon Alrae
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 10+ messages in thread
From: Leon Alrae @ 2015-06-03  9:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: james.hogan, aurelien

Extend EntryLo0, EntryLo1, LLAddr and TagLo from 32 to 64 bits in MIPS32.

Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
---
 target-mips/cpu.h       | 14 +++++++-------
 target-mips/machine.c   | 20 ++++++++++----------
 target-mips/op_helper.c |  8 ++++----
 target-mips/translate.c |  5 +++--
 4 files changed, 24 insertions(+), 23 deletions(-)

diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 03eb888..2dfa139 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -34,7 +34,7 @@ struct r4k_tlb_t {
     uint_fast16_t RI0:1;
     uint_fast16_t RI1:1;
     uint_fast16_t EHINV:1;
-    target_ulong PFN[2];
+    uint64_t PFN[2];
 };
 
 #if !defined(CONFIG_USER_ONLY)
@@ -225,7 +225,7 @@ struct CPUMIPSState {
     uint32_t SEGBITS;
     uint32_t PABITS;
     target_ulong SEGMask;
-    target_ulong PAMask;
+    uint64_t PAMask;
 
     int32_t msair;
 #define MSAIR_ProcID    8
@@ -273,8 +273,8 @@ struct CPUMIPSState {
 #define CP0VPEOpt_DWX2	2
 #define CP0VPEOpt_DWX1	1
 #define CP0VPEOpt_DWX0	0
-    target_ulong CP0_EntryLo0;
-    target_ulong CP0_EntryLo1;
+    uint64_t CP0_EntryLo0;
+    uint64_t CP0_EntryLo1;
 #if defined(TARGET_MIPS64)
 # define CP0EnLo_RI 63
 # define CP0EnLo_XI 62
@@ -471,11 +471,11 @@ struct CPUMIPSState {
     int32_t CP0_Config6;
     int32_t CP0_Config7;
     /* XXX: Maybe make LLAddr per-TC? */
-    target_ulong lladdr;
+    uint64_t lladdr;
     target_ulong llval;
     target_ulong llnewval;
     target_ulong llreg;
-    target_ulong CP0_LLAddr_rw_bitmask;
+    uint64_t CP0_LLAddr_rw_bitmask;
     int CP0_LLAddr_shift;
     target_ulong CP0_WatchLo[8];
     int32_t CP0_WatchHi[8];
@@ -502,7 +502,7 @@ struct CPUMIPSState {
 #define CP0DB_DSS  0
     target_ulong CP0_DEPC;
     int32_t CP0_Performance0;
-    int32_t CP0_TagLo;
+    uint64_t CP0_TagLo;
     int32_t CP0_DataLo;
     int32_t CP0_TagHi;
     int32_t CP0_DataHi;
diff --git a/target-mips/machine.c b/target-mips/machine.c
index 7d1fa32..559402c 100644
--- a/target-mips/machine.c
+++ b/target-mips/machine.c
@@ -142,8 +142,8 @@ static int get_tlb(QEMUFile *f, void *pv, size_t size)
     v->RI0 = (flags >> 13) & 1;
     v->XI1 = (flags >> 12) & 1;
     v->XI0 = (flags >> 11) & 1;
-    qemu_get_betls(f, &v->PFN[0]);
-    qemu_get_betls(f, &v->PFN[1]);
+    qemu_get_be64s(f, &v->PFN[0]);
+    qemu_get_be64s(f, &v->PFN[1]);
 
     return 0;
 }
@@ -169,8 +169,8 @@ static void put_tlb(QEMUFile *f, void *pv, size_t size)
     qemu_put_be32s(f, &v->PageMask);
     qemu_put_8s(f, &v->ASID);
     qemu_put_be16s(f, &flags);
-    qemu_put_betls(f, &v->PFN[0]);
-    qemu_put_betls(f, &v->PFN[1]);
+    qemu_put_be64s(f, &v->PFN[0]);
+    qemu_put_be64s(f, &v->PFN[1]);
 }
 
 const VMStateInfo vmstate_info_tlb = {
@@ -201,8 +201,8 @@ const VMStateDescription vmstate_tlb = {
 
 const VMStateDescription vmstate_mips_cpu = {
     .name = "cpu",
-    .version_id = 6,
-    .minimum_version_id = 6,
+    .version_id = 7,
+    .minimum_version_id = 7,
     .post_load = cpu_post_load,
     .fields = (VMStateField[]) {
         /* Active TC */
@@ -237,8 +237,8 @@ const VMStateDescription vmstate_mips_cpu = {
         VMSTATE_UINTTL(env.CP0_VPESchedule, MIPSCPU),
         VMSTATE_UINTTL(env.CP0_VPEScheFBack, MIPSCPU),
         VMSTATE_INT32(env.CP0_VPEOpt, MIPSCPU),
-        VMSTATE_UINTTL(env.CP0_EntryLo0, MIPSCPU),
-        VMSTATE_UINTTL(env.CP0_EntryLo1, MIPSCPU),
+        VMSTATE_UINT64(env.CP0_EntryLo0, MIPSCPU),
+        VMSTATE_UINT64(env.CP0_EntryLo1, MIPSCPU),
         VMSTATE_UINTTL(env.CP0_Context, MIPSCPU),
         VMSTATE_INT32(env.CP0_PageMask, MIPSCPU),
         VMSTATE_INT32(env.CP0_PageGrain, MIPSCPU),
@@ -269,7 +269,7 @@ const VMStateDescription vmstate_mips_cpu = {
         VMSTATE_INT32(env.CP0_Config3, MIPSCPU),
         VMSTATE_INT32(env.CP0_Config6, MIPSCPU),
         VMSTATE_INT32(env.CP0_Config7, MIPSCPU),
-        VMSTATE_UINTTL(env.lladdr, MIPSCPU),
+        VMSTATE_UINT64(env.lladdr, MIPSCPU),
         VMSTATE_UINTTL_ARRAY(env.CP0_WatchLo, MIPSCPU, 8),
         VMSTATE_INT32_ARRAY(env.CP0_WatchHi, MIPSCPU, 8),
         VMSTATE_UINTTL(env.CP0_XContext, MIPSCPU),
@@ -277,7 +277,7 @@ const VMStateDescription vmstate_mips_cpu = {
         VMSTATE_INT32(env.CP0_Debug, MIPSCPU),
         VMSTATE_UINTTL(env.CP0_DEPC, MIPSCPU),
         VMSTATE_INT32(env.CP0_Performance0, MIPSCPU),
-        VMSTATE_INT32(env.CP0_TagLo, MIPSCPU),
+        VMSTATE_UINT64(env.CP0_TagLo, MIPSCPU),
         VMSTATE_INT32(env.CP0_DataLo, MIPSCPU),
         VMSTATE_INT32(env.CP0_TagHi, MIPSCPU),
         VMSTATE_INT32(env.CP0_DataHi, MIPSCPU),
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 89ddad2..445c4b2 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -1996,12 +1996,12 @@ void r4k_helper_tlbr(CPUMIPSState *env)
         env->CP0_EntryHi = tlb->VPN | tlb->ASID;
         env->CP0_PageMask = tlb->PageMask;
         env->CP0_EntryLo0 = tlb->G | (tlb->V0 << 1) | (tlb->D0 << 2) |
-                        ((target_ulong)tlb->RI0 << CP0EnLo_RI) |
-                        ((target_ulong)tlb->XI0 << CP0EnLo_XI) |
+                        ((uint64_t)tlb->RI0 << CP0EnLo_RI) |
+                        ((uint64_t)tlb->XI0 << CP0EnLo_XI) |
                         (tlb->C0 << 3) | (tlb->PFN[0] >> 6);
         env->CP0_EntryLo1 = tlb->G | (tlb->V1 << 1) | (tlb->D1 << 2) |
-                        ((target_ulong)tlb->RI1 << CP0EnLo_RI) |
-                        ((target_ulong)tlb->XI1 << CP0EnLo_XI) |
+                        ((uint64_t)tlb->RI1 << CP0EnLo_RI) |
+                        ((uint64_t)tlb->XI1 << CP0EnLo_XI) |
                         (tlb->C1 << 3) | (tlb->PFN[1] >> 6);
     }
 }
diff --git a/target-mips/translate.c b/target-mips/translate.c
index fe6bc16..94936d4 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -19413,7 +19413,8 @@ void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
 
     cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
                 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
-    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
+    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
+                PRIx64 "\n",
                 env->CP0_Config0, env->CP0_Config1, env->lladdr);
     cpu_fprintf(f, "    Config2 0x%08x Config3 0x%08x\n",
                 env->CP0_Config2, env->CP0_Config3);
@@ -19547,7 +19548,7 @@ void cpu_state_reset(CPUMIPSState *env)
     }
 #endif
     env->PABITS = env->cpu_model->PABITS;
-    env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
+    env->PAMask = (1ULL << env->cpu_model->PABITS) - 1;
     env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
     env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
     env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;

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

* [Qemu-devel] [PATCH v2 2/7] target-mips: support Page Frame Number Extension field
  2015-06-03  9:32 [Qemu-devel] [PATCH v2 0/7] target-mips: add support for large physical addresses Leon Alrae
  2015-06-03  9:32 ` [Qemu-devel] [PATCH v2 1/7] target-mips: extend selected CP0 registers to 64-bits in MIPS32 Leon Alrae
@ 2015-06-03  9:32 ` Leon Alrae
  2015-06-03  9:32 ` [Qemu-devel] [PATCH v2 3/7] target-mips: add CP0.PageGrain.ELPA support Leon Alrae
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Leon Alrae @ 2015-06-03  9:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: james.hogan, aurelien

Update tlb->PFN to contain PFN concatenated with PFNX. PFNX is 0 if large
physical address is not supported.

Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
---
 target-mips/op_helper.c | 32 ++++++++++++++++++++++++++------
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 445c4b2..32c3937 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -1825,6 +1825,16 @@ static void r4k_mips_tlb_flush_extra (CPUMIPSState *env, int first)
     }
 }
 
+static inline uint64_t get_tlb_pfn_from_entrylo(uint64_t entrylo)
+{
+#if defined(TARGET_MIPS64)
+    return extract64(entrylo, 6, 54);
+#else
+    return extract64(entrylo, 6, 24) | /* PFN */
+           (extract64(entrylo, 32, 32) << 24); /* PFNX */
+#endif
+}
+
 static void r4k_fill_tlb(CPUMIPSState *env, int idx)
 {
     r4k_tlb_t *tlb;
@@ -1848,13 +1858,13 @@ static void r4k_fill_tlb(CPUMIPSState *env, int idx)
     tlb->C0 = (env->CP0_EntryLo0 >> 3) & 0x7;
     tlb->XI0 = (env->CP0_EntryLo0 >> CP0EnLo_XI) & 1;
     tlb->RI0 = (env->CP0_EntryLo0 >> CP0EnLo_RI) & 1;
-    tlb->PFN[0] = (env->CP0_EntryLo0 >> 6) << 12;
+    tlb->PFN[0] = get_tlb_pfn_from_entrylo(env->CP0_EntryLo0) << 12;
     tlb->V1 = (env->CP0_EntryLo1 & 2) != 0;
     tlb->D1 = (env->CP0_EntryLo1 & 4) != 0;
     tlb->C1 = (env->CP0_EntryLo1 >> 3) & 0x7;
     tlb->XI1 = (env->CP0_EntryLo1 >> CP0EnLo_XI) & 1;
     tlb->RI1 = (env->CP0_EntryLo1 >> CP0EnLo_RI) & 1;
-    tlb->PFN[1] = (env->CP0_EntryLo1 >> 6) << 12;
+    tlb->PFN[1] = get_tlb_pfn_from_entrylo(env->CP0_EntryLo1) << 12;
 }
 
 void r4k_helper_tlbinv(CPUMIPSState *env)
@@ -1971,6 +1981,16 @@ void r4k_helper_tlbp(CPUMIPSState *env)
     }
 }
 
+static inline uint64_t get_entrylo_pfn_from_tlb(uint64_t tlb_pfn)
+{
+#if defined(TARGET_MIPS64)
+    return tlb_pfn << 6;
+#else
+    return (extract64(tlb_pfn, 0, 24) << 6) | /* PFN */
+           (extract64(tlb_pfn, 24, 32) << 32); /* PFNX */
+#endif
+}
+
 void r4k_helper_tlbr(CPUMIPSState *env)
 {
     r4k_tlb_t *tlb;
@@ -1997,12 +2017,12 @@ void r4k_helper_tlbr(CPUMIPSState *env)
         env->CP0_PageMask = tlb->PageMask;
         env->CP0_EntryLo0 = tlb->G | (tlb->V0 << 1) | (tlb->D0 << 2) |
                         ((uint64_t)tlb->RI0 << CP0EnLo_RI) |
-                        ((uint64_t)tlb->XI0 << CP0EnLo_XI) |
-                        (tlb->C0 << 3) | (tlb->PFN[0] >> 6);
+                        ((uint64_t)tlb->XI0 << CP0EnLo_XI) | (tlb->C0 << 3) |
+                        get_entrylo_pfn_from_tlb(tlb->PFN[0] >> 12);
         env->CP0_EntryLo1 = tlb->G | (tlb->V1 << 1) | (tlb->D1 << 2) |
                         ((uint64_t)tlb->RI1 << CP0EnLo_RI) |
-                        ((uint64_t)tlb->XI1 << CP0EnLo_XI) |
-                        (tlb->C1 << 3) | (tlb->PFN[1] >> 6);
+                        ((uint64_t)tlb->XI1 << CP0EnLo_XI) | (tlb->C1 << 3) |
+                        get_entrylo_pfn_from_tlb(tlb->PFN[1] >> 12);
     }
 }
 

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

* [Qemu-devel] [PATCH v2 3/7] target-mips: add CP0.PageGrain.ELPA support
  2015-06-03  9:32 [Qemu-devel] [PATCH v2 0/7] target-mips: add support for large physical addresses Leon Alrae
  2015-06-03  9:32 ` [Qemu-devel] [PATCH v2 1/7] target-mips: extend selected CP0 registers to 64-bits in MIPS32 Leon Alrae
  2015-06-03  9:32 ` [Qemu-devel] [PATCH v2 2/7] target-mips: support Page Frame Number Extension field Leon Alrae
@ 2015-06-03  9:32 ` Leon Alrae
  2015-06-03  9:32 ` [Qemu-devel] [PATCH v2 4/7] target-mips: add MTHC0 and MFHC0 instructions Leon Alrae
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Leon Alrae @ 2015-06-03  9:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: james.hogan, aurelien

CP0.PageGrain.ELPA enables support for large physical addresses. This field
is encoded as follows:
0: Large physical address support is disabled.
1: Large physical address support is enabled.

If this bit is a 1, the following changes occur to coprocessor 0 registers:
- The PFNX field of the EntryLo0 and EntryLo1 registers is writable and
  concatenated with the PFN field to form the full page frame number.
- Access to optional COP0 registers with PA extension, LLAddr, TagLo is
  defined.

P5600 can operate in 32-bit or 40-bit Physical Address Mode. Therefore if
XPA is disabled (CP0.PageGrain.ELPA = 0) then assume 32-bit Address Mode.
In MIPS64 assume 36 as default PABITS (when CP0.PageGrain.ELPA = 0).

env->PABITS value is constant and indicates maximum PABITS available on
a core, whereas env->PAMask is calculated from env->PABITS and is also
affected by CP0.PageGrain.ELPA.

Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
---
 target-mips/cpu.h       | 27 +++++++++++++++++++++++++--
 target-mips/machine.c   |  1 +
 target-mips/mips-defs.h |  4 ++--
 target-mips/op_helper.c | 19 ++++++++++++-------
 target-mips/translate.c |  3 ++-
 5 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 2dfa139..e106bb8 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -224,8 +224,14 @@ struct CPUMIPSState {
 
     uint32_t SEGBITS;
     uint32_t PABITS;
+#if defined(TARGET_MIPS64)
+# define PABITS_BASE 36
+#else
+# define PABITS_BASE 32
+#endif
     target_ulong SEGMask;
     uint64_t PAMask;
+#define PAMASK_BASE ((1ULL << PABITS_BASE) - 1)
 
     int32_t msair;
 #define MSAIR_ProcID    8
@@ -289,6 +295,7 @@ struct CPUMIPSState {
     int32_t CP0_PageGrain;
 #define CP0PG_RIE 31
 #define CP0PG_XIE 30
+#define CP0PG_ELPA 29
 #define CP0PG_IEC 27
     int32_t CP0_Wired;
     int32_t CP0_SRSConf0_rw_bitmask;
@@ -517,7 +524,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  0x35807FF
+#define MIPS_HFLAG_TMASK  0x75807FF
 #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
@@ -565,6 +572,7 @@ struct CPUMIPSState {
 #define MIPS_HFLAG_FBNSLOT 0x800000 /* Forbidden slot                   */
 #define MIPS_HFLAG_MSA   0x1000000
 #define MIPS_HFLAG_FRE   0x2000000 /* FRE enabled */
+#define MIPS_HFLAG_ELPA  0x4000000
     target_ulong btarget;        /* Jump / branch target               */
     target_ulong bcond;          /* Branch condition (if needed)       */
 
@@ -800,6 +808,15 @@ static inline void restore_msa_fp_status(CPUMIPSState *env)
     set_flush_inputs_to_zero(flush_to_zero, status);
 }
 
+static inline void restore_pamask(CPUMIPSState *env)
+{
+    if (env->hflags & MIPS_HFLAG_ELPA) {
+        env->PAMask = (1ULL << env->PABITS) - 1;
+    } else {
+        env->PAMask = PAMASK_BASE;
+    }
+}
+
 static inline void cpu_get_tb_cpu_state(CPUMIPSState *env, target_ulong *pc,
                                         target_ulong *cs_base, int *flags)
 {
@@ -847,7 +864,8 @@ static inline void compute_hflags(CPUMIPSState *env)
     env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
                      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_SBRI | MIPS_HFLAG_MSA | MIPS_HFLAG_FRE |
+                     MIPS_HFLAG_ELPA);
     if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
         !(env->CP0_Status & (1 << CP0St_ERL)) &&
         !(env->hflags & MIPS_HFLAG_DM)) {
@@ -933,6 +951,11 @@ static inline void compute_hflags(CPUMIPSState *env)
             env->hflags |= MIPS_HFLAG_FRE;
         }
     }
+    if (env->CP0_Config3 & (1 << CP0C3_LPA)) {
+        if (env->CP0_PageGrain & (1 << CP0PG_ELPA)) {
+            env->hflags |= MIPS_HFLAG_ELPA;
+        }
+    }
 }
 
 #ifndef CONFIG_USER_ONLY
diff --git a/target-mips/machine.c b/target-mips/machine.c
index 559402c..8fa755c 100644
--- a/target-mips/machine.c
+++ b/target-mips/machine.c
@@ -10,6 +10,7 @@ static int cpu_post_load(void *opaque, int version_id)
     restore_fp_status(env);
     restore_msa_fp_status(env);
     compute_hflags(env);
+    restore_pamask(env);
 
     return 0;
 }
diff --git a/target-mips/mips-defs.h b/target-mips/mips-defs.h
index 1784227..20aa87c 100644
--- a/target-mips/mips-defs.h
+++ b/target-mips/mips-defs.h
@@ -10,11 +10,11 @@
 
 #if defined(TARGET_MIPS64)
 #define TARGET_LONG_BITS 64
-#define TARGET_PHYS_ADDR_SPACE_BITS 36
+#define TARGET_PHYS_ADDR_SPACE_BITS 48
 #define TARGET_VIRT_ADDR_SPACE_BITS 42
 #else
 #define TARGET_LONG_BITS 32
-#define TARGET_PHYS_ADDR_SPACE_BITS 36
+#define TARGET_PHYS_ADDR_SPACE_BITS 40
 #define TARGET_VIRT_ADDR_SPACE_BITS 32
 #endif
 
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 32c3937..5ca95c5 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -1067,19 +1067,23 @@ void helper_mtc0_vpeopt(CPUMIPSState *env, target_ulong arg1)
     env->CP0_VPEOpt = arg1 & 0x0000ffff;
 }
 
+#define MTC0_ENTRYLO_MASK(env) ((env->PAMask >> 6) & 0x3FFFFFFF)
+
 void helper_mtc0_entrylo0(CPUMIPSState *env, target_ulong arg1)
 {
-    /* Large physaddr (PABITS) not implemented */
     /* 1k pages not implemented */
     target_ulong rxi = arg1 & (env->CP0_PageGrain & (3u << CP0PG_XIE));
-    env->CP0_EntryLo0 = (arg1 & 0x3FFFFFFF) | (rxi << (CP0EnLo_XI - 30));
+    env->CP0_EntryLo0 = (arg1 & MTC0_ENTRYLO_MASK(env))
+                        | (rxi << (CP0EnLo_XI - 30));
 }
 
 #if defined(TARGET_MIPS64)
+#define DMTC0_ENTRYLO_MASK(env) (env->PAMask >> 6)
+
 void helper_dmtc0_entrylo0(CPUMIPSState *env, uint64_t arg1)
 {
     uint64_t rxi = arg1 & ((env->CP0_PageGrain & (3ull << CP0PG_XIE)) << 32);
-    env->CP0_EntryLo0 = (arg1 & 0x3FFFFFFF) | rxi;
+    env->CP0_EntryLo0 = (arg1 & DMTC0_ENTRYLO_MASK(env)) | rxi;
 }
 #endif
 
@@ -1245,17 +1249,17 @@ void helper_mttc0_tcschefback(CPUMIPSState *env, target_ulong arg1)
 
 void helper_mtc0_entrylo1(CPUMIPSState *env, target_ulong arg1)
 {
-    /* Large physaddr (PABITS) not implemented */
     /* 1k pages not implemented */
     target_ulong rxi = arg1 & (env->CP0_PageGrain & (3u << CP0PG_XIE));
-    env->CP0_EntryLo1 = (arg1 & 0x3FFFFFFF) | (rxi << (CP0EnLo_XI - 30));
+    env->CP0_EntryLo1 = (arg1 & MTC0_ENTRYLO_MASK(env))
+                        | (rxi << (CP0EnLo_XI - 30));
 }
 
 #if defined(TARGET_MIPS64)
 void helper_dmtc0_entrylo1(CPUMIPSState *env, uint64_t arg1)
 {
     uint64_t rxi = arg1 & ((env->CP0_PageGrain & (3ull << CP0PG_XIE)) << 32);
-    env->CP0_EntryLo1 = (arg1 & 0x3FFFFFFF) | rxi;
+    env->CP0_EntryLo1 = (arg1 & DMTC0_ENTRYLO_MASK(env)) | rxi;
 }
 #endif
 
@@ -1278,10 +1282,11 @@ void helper_mtc0_pagemask(CPUMIPSState *env, target_ulong arg1)
 void helper_mtc0_pagegrain(CPUMIPSState *env, target_ulong arg1)
 {
     /* SmartMIPS not implemented */
-    /* Large physaddr (PABITS) not implemented */
     /* 1k pages not implemented */
     env->CP0_PageGrain = (arg1 & env->CP0_PageGrain_rw_bitmask) |
                          (env->CP0_PageGrain & ~env->CP0_PageGrain_rw_bitmask);
+    compute_hflags(env);
+    restore_pamask(env);
 }
 
 void helper_mtc0_wired(CPUMIPSState *env, target_ulong arg1)
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 94936d4..9b77816 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -5679,6 +5679,7 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
             check_insn(ctx, ISA_MIPS32R2);
             gen_helper_mtc0_pagegrain(cpu_env, arg);
             rn = "PageGrain";
+            ctx->bstate = BS_STOP;
             break;
         default:
             goto cp0_unimplemented;
@@ -19548,7 +19549,6 @@ void cpu_state_reset(CPUMIPSState *env)
     }
 #endif
     env->PABITS = env->cpu_model->PABITS;
-    env->PAMask = (1ULL << env->cpu_model->PABITS) - 1;
     env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
     env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
     env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
@@ -19669,6 +19669,7 @@ void cpu_state_reset(CPUMIPSState *env)
     compute_hflags(env);
     restore_rounding_mode(env);
     restore_flush_mode(env);
+    restore_pamask(env);
     cs->exception_index = EXCP_NONE;
 }
 

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

* [Qemu-devel] [PATCH v2 4/7] target-mips: add MTHC0 and MFHC0 instructions
  2015-06-03  9:32 [Qemu-devel] [PATCH v2 0/7] target-mips: add support for large physical addresses Leon Alrae
                   ` (2 preceding siblings ...)
  2015-06-03  9:32 ` [Qemu-devel] [PATCH v2 3/7] target-mips: add CP0.PageGrain.ELPA support Leon Alrae
@ 2015-06-03  9:32 ` Leon Alrae
  2015-06-03  9:32 ` [Qemu-devel] [PATCH v2 5/7] target-mips: correct MFC0 for CP0.EntryLo in MIPS64 Leon Alrae
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Leon Alrae @ 2015-06-03  9:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: james.hogan, aurelien

Implement MTHC0 and MFHC0 instructions. In MIPS32 they are used to access
upper word of extended to 64-bits CP0 registers.

In MIPS64, when CP0 destination register specified is the EntryLo0 or
EntryLo1, bits 1:0 of the GPR appear at bits 31:30 of EntryLo0 or
EntryLo1. This is to compensate for RI and XI, which were shifted to bits
63:62 by MTC0 to EntryLo0 or EntryLo1. Therefore creating separate
functions for EntryLo0 and EntryLo1.

Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
---
 disas/mips.c            |   2 +
 target-mips/cpu.h       |   1 +
 target-mips/translate.c | 229 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 232 insertions(+)

diff --git a/disas/mips.c b/disas/mips.c
index 1afe0c5..8aaa87c 100644
--- a/disas/mips.c
+++ b/disas/mips.c
@@ -2238,6 +2238,8 @@ const struct mips_opcode mips_builtin_opcodes[] =
 {"ceil.l.s", "D,S",	0x4600000a, 0xffff003f, WR_D|RD_S|FP_S|FP_D,	0,		I3|I33	},
 {"ceil.w.d", "D,S",	0x4620000e, 0xffff003f, WR_D|RD_S|FP_S|FP_D,	0,		I2	},
 {"ceil.w.s", "D,S",	0x4600000e, 0xffff003f, WR_D|RD_S|FP_S,		0,		I2	},
+{"mfhc0",   "t,G,H",    0x40400000, 0xffe007f8, LCD|WR_t|RD_C0,       0, I33},
+{"mthc0",   "t,G,H",    0x40c00000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC, 0, I33},
 {"cfc0",    "t,G",	0x40400000, 0xffe007ff,	LCD|WR_t|RD_C0,		0,		I1	},
 {"cfc1",    "t,G",	0x44400000, 0xffe007ff,	LCD|WR_t|RD_C1|FP_S,	0,		I1	},
 {"cfc1",    "t,S",	0x44400000, 0xffe007ff,	LCD|WR_t|RD_C1|FP_S,	0,		I1	},
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index e106bb8..7b5ef36 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -473,6 +473,7 @@ struct CPUMIPSState {
 #define CP0C5_UFE        9
 #define CP0C5_FRE        8
 #define CP0C5_SBRI       6
+#define CP0C5_MVH        5
 #define CP0C5_UFR        2
 #define CP0C5_NFExists   0
     int32_t CP0_Config6;
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 9b77816..c931eda 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -868,8 +868,10 @@ enum {
 enum {
     OPC_MFC0     = (0x00 << 21) | OPC_CP0,
     OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
+    OPC_MFHC0    = (0x02 << 21) | OPC_CP0,
     OPC_MTC0     = (0x04 << 21) | OPC_CP0,
     OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
+    OPC_MTHC0    = (0x06 << 21) | OPC_CP0,
     OPC_MFTR     = (0x08 << 21) | OPC_CP0,
     OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
     OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
@@ -1424,6 +1426,9 @@ typedef struct DisasContext {
     int ie;
     bool bi;
     bool bp;
+    uint64_t PAMask;
+    bool mvh;
+    int CP0_LLAddr_shift;
 } DisasContext;
 
 enum {
@@ -1770,6 +1775,13 @@ static inline void check_cp1_registers(DisasContext *ctx, int regs)
    This is enabled by CP0 Status register MX(24) bit.
  */
 
+static inline void check_mvh(DisasContext *ctx)
+{
+    if (unlikely(!ctx->mvh)) {
+        generate_exception(ctx, EXCP_RI);
+    }
+}
+
 static inline void check_dsp(DisasContext *ctx)
 {
     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
@@ -4833,6 +4845,65 @@ static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
 
 #ifndef CONFIG_USER_ONLY
 /* CP0 (MMU and control) */
+static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
+{
+    TCGv_i64 t0 = tcg_temp_new_i64();
+    TCGv_i64 t1 = tcg_temp_new_i64();
+
+    tcg_gen_ext_tl_i64(t0, arg);
+    tcg_gen_ld_i64(t1, cpu_env, off);
+#if defined(TARGET_MIPS64)
+    tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
+#else
+    tcg_gen_concat32_i64(t1, t1, t0);
+#endif
+    tcg_gen_st_i64(t1, cpu_env, off);
+    tcg_temp_free_i64(t1);
+    tcg_temp_free_i64(t0);
+}
+
+static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
+{
+    TCGv_i64 t0 = tcg_temp_new_i64();
+    TCGv_i64 t1 = tcg_temp_new_i64();
+
+    tcg_gen_ext_tl_i64(t0, arg);
+    tcg_gen_ld_i64(t1, cpu_env, off);
+    tcg_gen_concat32_i64(t1, t1, t0);
+    tcg_gen_st_i64(t1, cpu_env, off);
+    tcg_temp_free_i64(t1);
+    tcg_temp_free_i64(t0);
+}
+
+static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
+{
+    TCGv_i64 t0 = tcg_temp_new_i64();
+
+    tcg_gen_ld_i64(t0, cpu_env, off);
+#if defined(TARGET_MIPS64)
+    tcg_gen_shri_i64(t0, t0, 30);
+    tcg_gen_ext32s_tl(arg, t0);
+#else
+    tcg_gen_shri_i64(t0, t0, 32);
+    tcg_gen_trunc_i64_tl(arg, t0);
+#endif
+    tcg_temp_free_i64(t0);
+}
+
+static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
+{
+    TCGv_i64 t0 = tcg_temp_new_i64();
+
+    tcg_gen_ld_i64(t0, cpu_env, off);
+    tcg_gen_shri_i64(t0, t0, 32 + shift);
+#if defined(TARGET_MIPS64)
+    tcg_gen_ext32s_tl(arg, t0);
+#else
+    tcg_gen_trunc_i64_tl(arg, t0);
+#endif
+    tcg_temp_free_i64(t0);
+}
+
 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
 {
     TCGv_i32 t0 = tcg_temp_new_i32();
@@ -4863,6 +4934,140 @@ static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
     tcg_gen_st_tl(arg, cpu_env, off);
 }
 
+static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
+{
+    const char *rn = "invalid";
+
+    if (!(ctx->hflags & MIPS_HFLAG_ELPA)) {
+        goto mfhc0_read_zero;
+    }
+
+    switch (reg) {
+    case 2:
+        switch (sel) {
+        case 0:
+            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
+            rn = "EntryLo0";
+            break;
+        default:
+            goto mfhc0_read_zero;
+        }
+        break;
+    case 3:
+        switch (sel) {
+        case 0:
+            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
+            rn = "EntryLo1";
+            break;
+        default:
+            goto mfhc0_read_zero;
+        }
+        break;
+    case 17:
+        switch (sel) {
+        case 0:
+            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
+                             ctx->CP0_LLAddr_shift);
+            rn = "LLAddr";
+            break;
+        default:
+            goto mfhc0_read_zero;
+        }
+        break;
+    case 28:
+        switch (sel) {
+        case 0:
+        case 2:
+        case 4:
+        case 6:
+            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
+            rn = "TagLo";
+            break;
+        default:
+            goto mfhc0_read_zero;
+        }
+        break;
+    default:
+        goto mfhc0_read_zero;
+    }
+
+    (void)rn; /* avoid a compiler warning */
+    LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
+    return;
+
+mfhc0_read_zero:
+    LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
+    tcg_gen_movi_tl(arg, 0);
+}
+
+static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
+{
+    const char *rn = "invalid";
+    uint64_t mask = ctx->PAMask >> 36;
+
+    if (!(ctx->hflags & MIPS_HFLAG_ELPA)) {
+        goto mthc0_nop;
+    }
+
+    switch (reg) {
+    case 2:
+        switch (sel) {
+        case 0:
+            tcg_gen_andi_tl(arg, arg, mask);
+            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
+            rn = "EntryLo0";
+            break;
+        default:
+            goto mthc0_nop;
+        }
+        break;
+    case 3:
+        switch (sel) {
+        case 0:
+            tcg_gen_andi_tl(arg, arg, mask);
+            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
+            rn = "EntryLo1";
+            break;
+        default:
+            goto mthc0_nop;
+        }
+        break;
+    case 17:
+        switch (sel) {
+        case 0:
+            /* LLAddr is read-only (the only exception is bit 0 if LLB is
+               supported); the CP0_LLAddr_rw_bitmask does not seem to be
+               relevant for modern MIPS cores supporting MTHC0, therefore
+               treating MTHC0 to LLAddr as NOP. */
+            rn = "LLAddr";
+            break;
+        default:
+            goto mthc0_nop;
+        }
+        break;
+    case 28:
+        switch (sel) {
+        case 0:
+        case 2:
+        case 4:
+        case 6:
+            tcg_gen_andi_tl(arg, arg, mask);
+            gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
+            rn = "TagLo";
+            break;
+        default:
+            goto mthc0_nop;
+        }
+        break;
+    default:
+        goto mthc0_nop;
+    }
+
+    (void)rn; /* avoid a compiler warning */
+mthc0_nop:
+    LOG_DISAS("mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
+}
+
 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
 {
     if (ctx->insn_flags & ISA_MIPS32R6) {
@@ -7860,6 +8065,25 @@ static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt,
         opn = "dmtc0";
         break;
 #endif
+    case OPC_MFHC0:
+        check_mvh(ctx);
+        if (rt == 0) {
+            /* Treat as NOP. */
+            return;
+        }
+        gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
+        opn = "mfhc0";
+        break;
+    case OPC_MTHC0:
+        check_mvh(ctx);
+        {
+            TCGv t0 = tcg_temp_new();
+            gen_load_gpr(t0, rt);
+            gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
+            tcg_temp_free(t0);
+        }
+        opn = "mthc0";
+        break;
     case OPC_MFTR:
         check_insn(ctx, ASE_MT);
         if (rd == 0) {
@@ -18591,6 +18815,8 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
         case OPC_MTC0:
         case OPC_MFTR:
         case OPC_MTTR:
+        case OPC_MFHC0:
+        case OPC_MTHC0:
 #if defined(TARGET_MIPS64)
         case OPC_DMFC0:
         case OPC_DMTC0:
@@ -19161,6 +19387,9 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
     ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
     ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
     ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
+    ctx.PAMask = env->PAMask;
+    ctx.mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
+    ctx.CP0_LLAddr_shift = env->CP0_LLAddr_shift;
     /* Restore delay slot state from the tb context.  */
     ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
     ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;

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

* [Qemu-devel] [PATCH v2 5/7] target-mips: correct MFC0 for CP0.EntryLo in MIPS64
  2015-06-03  9:32 [Qemu-devel] [PATCH v2 0/7] target-mips: add support for large physical addresses Leon Alrae
                   ` (3 preceding siblings ...)
  2015-06-03  9:32 ` [Qemu-devel] [PATCH v2 4/7] target-mips: add MTHC0 and MFHC0 instructions Leon Alrae
@ 2015-06-03  9:32 ` Leon Alrae
  2015-06-03  9:32 ` [Qemu-devel] [PATCH v2 6/7] target-mips: remove misleading comments in translate_init.c Leon Alrae
  2015-06-03  9:32 ` [Qemu-devel] [PATCH v2 7/7] target-mips: enable XPA and LPA features Leon Alrae
  6 siblings, 0 replies; 10+ messages in thread
From: Leon Alrae @ 2015-06-03  9:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: james.hogan, aurelien

Since PFNX is now supported the bits 31:30 have to be cleared.

Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
---
 target-mips/translate.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index c931eda..0ca610c 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -5169,10 +5169,10 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
 #if defined(TARGET_MIPS64)
             if (ctx->rxi) {
+                /* Move RI/XI fields to bits 31:30 */
                 TCGv tmp = tcg_temp_new();
-                tcg_gen_andi_tl(tmp, arg, (3ull << CP0EnLo_XI));
-                tcg_gen_shri_tl(tmp, tmp, 32);
-                tcg_gen_or_tl(arg, arg, tmp);
+                tcg_gen_shri_tl(tmp, arg, CP0EnLo_XI);
+                tcg_gen_deposit_tl(arg, arg, tmp, 30, 2);
                 tcg_temp_free(tmp);
             }
 #endif
@@ -5224,10 +5224,10 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
 #if defined(TARGET_MIPS64)
             if (ctx->rxi) {
+                /* Move RI/XI fields to bits 31:30 */
                 TCGv tmp = tcg_temp_new();
-                tcg_gen_andi_tl(tmp, arg, (3ull << CP0EnLo_XI));
-                tcg_gen_shri_tl(tmp, tmp, 32);
-                tcg_gen_or_tl(arg, arg, tmp);
+                tcg_gen_shri_tl(tmp, arg, CP0EnLo_XI);
+                tcg_gen_deposit_tl(arg, arg, tmp, 30, 2);
                 tcg_temp_free(tmp);
             }
 #endif

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

* [Qemu-devel] [PATCH v2 6/7] target-mips: remove misleading comments in translate_init.c
  2015-06-03  9:32 [Qemu-devel] [PATCH v2 0/7] target-mips: add support for large physical addresses Leon Alrae
                   ` (4 preceding siblings ...)
  2015-06-03  9:32 ` [Qemu-devel] [PATCH v2 5/7] target-mips: correct MFC0 for CP0.EntryLo in MIPS64 Leon Alrae
@ 2015-06-03  9:32 ` Leon Alrae
  2015-06-03  9:32 ` [Qemu-devel] [PATCH v2 7/7] target-mips: enable XPA and LPA features Leon Alrae
  6 siblings, 0 replies; 10+ messages in thread
From: Leon Alrae @ 2015-06-03  9:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: james.hogan, aurelien

PABITS are not hardcoded to 36 bits and we do not model 59 PABITS (which is
the architectural limit) in QEMU.

Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
---
 target-mips/translate_init.c | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c
index 00369f1..05a02eb 100644
--- a/target-mips/translate_init.c
+++ b/target-mips/translate_init.c
@@ -553,9 +553,6 @@ static const mips_def_t mips_defs[] =
                     (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) |
                     (1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV),
         .SEGBITS = 42,
-        /* The architectural limit is 59, but we have hardcoded 36 bit
-           in some places...
-        .PABITS = 59, */ /* the architectural limit */
         .PABITS = 36,
         .insn_flags = CPU_MIPS64R2 | ASE_MIPS3D,
         .mmu_type = MMU_TYPE_R4000,
@@ -636,9 +633,6 @@ static const mips_def_t mips_defs[] =
                     (1 << FCR0_W) | (1 << FCR0_D) | (1 << FCR0_S) |
                     (0x00 << FCR0_PRID) | (0x0 << FCR0_REV),
         .SEGBITS = 42,
-        /* The architectural limit is 59, but we have hardcoded 36 bit
-           in some places...
-        .PABITS = 59, */ /* the architectural limit */
         .PABITS = 36,
         .insn_flags = CPU_MIPS64R6,
         .mmu_type = MMU_TYPE_R4000,
@@ -702,9 +696,6 @@ static const mips_def_t mips_defs[] =
                     (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) |
                     (1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV),
         .SEGBITS = 42,
-        /* The architectural limit is 59, but we have hardcoded 36 bit
-           in some places...
-        .PABITS = 59, */ /* the architectural limit */
         .PABITS = 36,
         .insn_flags = CPU_MIPS64R2 | ASE_DSP | ASE_DSPR2,
         .mmu_type = MMU_TYPE_R4000,

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

* [Qemu-devel] [PATCH v2 7/7] target-mips: enable XPA and LPA features
  2015-06-03  9:32 [Qemu-devel] [PATCH v2 0/7] target-mips: add support for large physical addresses Leon Alrae
                   ` (5 preceding siblings ...)
  2015-06-03  9:32 ` [Qemu-devel] [PATCH v2 6/7] target-mips: remove misleading comments in translate_init.c Leon Alrae
@ 2015-06-03  9:32 ` Leon Alrae
  6 siblings, 0 replies; 10+ messages in thread
From: Leon Alrae @ 2015-06-03  9:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: james.hogan, aurelien

Enable XPA in MIPS32R5-generic and LPA in MIPS64R6-generic.

Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
---
 target-mips/translate_init.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c
index 05a02eb..836b7bf 100644
--- a/target-mips/translate_init.c
+++ b/target-mips/translate_init.c
@@ -400,10 +400,11 @@ static const mips_def_t mips_defs[] =
                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) |
                        (1 << CP0C1_CA),
         .CP0_Config2 = MIPS_CONFIG2,
-        .CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | (1 << CP0C3_MSAP),
+        .CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | (1 << CP0C3_MSAP) |
+                       (1 << CP0C3_LPA),
         .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M),
         .CP0_Config4_rw_bitmask = 0,
-        .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_UFR),
+        .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_UFR) | (1 << CP0C5_MVH),
         .CP0_Config5_rw_bitmask = (0 << CP0C5_M) | (1 << CP0C5_K) |
                                   (1 << CP0C5_CV) | (0 << CP0C5_EVA) |
                                   (1 << CP0C5_MSAEn) | (1 << CP0C5_UFR) |
@@ -413,11 +414,12 @@ static const mips_def_t mips_defs[] =
         .SYNCI_Step = 32,
         .CCRes = 2,
         .CP0_Status_rw_bitmask = 0x3778FF1F,
+        .CP0_PageGrain_rw_bitmask = (1 << CP0PG_ELPA),
         .CP1_fcr0 = (1 << FCR0_UFRP) | (1 << FCR0_F64) | (1 << FCR0_L) |
                     (1 << FCR0_W) | (1 << FCR0_D) | (1 << FCR0_S) |
                     (0x93 << FCR0_PRID),
         .SEGBITS = 32,
-        .PABITS = 32,
+        .PABITS = 40,
         .insn_flags = CPU_MIPS32R5 | ASE_MIPS16 | ASE_MSA,
         .mmu_type = MMU_TYPE_R4000,
     },
@@ -616,7 +618,8 @@ static const mips_def_t mips_defs[] =
                        (0 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
         .CP0_Config2 = MIPS_CONFIG2,
         .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_RXI) | (1 << CP0C3_BP) |
-                       (1 << CP0C3_BI) | (1 << CP0C3_ULRI) | (1U << CP0C3_M),
+                       (1 << CP0C3_BI) | (1 << CP0C3_ULRI) | (1 << CP0C3_LPA) |
+                       (1U << CP0C3_M),
         .CP0_Config4 = MIPS_CONFIG4 | (0xfc << CP0C4_KScrExist) |
                        (3 << CP0C4_IE) | (1 << CP0C4_M),
         .CP0_Config5_rw_bitmask = (1 << CP0C5_SBRI) | (1 << CP0C5_FRE) |
@@ -628,12 +631,12 @@ static const mips_def_t mips_defs[] =
         .CP0_Status_rw_bitmask = 0x30D8FFFF,
         .CP0_PageGrain = (1 << CP0PG_IEC) | (1 << CP0PG_XIE) |
                          (1U << CP0PG_RIE),
-        .CP0_PageGrain_rw_bitmask = 0,
+        .CP0_PageGrain_rw_bitmask = (1 << CP0PG_ELPA),
         .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_F64) | (1 << FCR0_L) |
                     (1 << FCR0_W) | (1 << FCR0_D) | (1 << FCR0_S) |
                     (0x00 << FCR0_PRID) | (0x0 << FCR0_REV),
         .SEGBITS = 42,
-        .PABITS = 36,
+        .PABITS = 48,
         .insn_flags = CPU_MIPS64R6,
         .mmu_type = MMU_TYPE_R4000,
     },

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

* Re: [Qemu-devel] [PATCH v2 1/7] target-mips: extend selected CP0 registers to 64-bits in MIPS32
  2015-06-03  9:32 ` [Qemu-devel] [PATCH v2 1/7] target-mips: extend selected CP0 registers to 64-bits in MIPS32 Leon Alrae
@ 2015-06-04 22:14   ` Aurelien Jarno
  2015-06-05 19:48     ` Leon Alrae
  0 siblings, 1 reply; 10+ messages in thread
From: Aurelien Jarno @ 2015-06-04 22:14 UTC (permalink / raw)
  To: Leon Alrae; +Cc: james.hogan, qemu-devel

On 2015-06-03 10:32, Leon Alrae wrote:
> Extend EntryLo0, EntryLo1, LLAddr and TagLo from 32 to 64 bits in MIPS32.
> 
> Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
> ---
>  target-mips/cpu.h       | 14 +++++++-------
>  target-mips/machine.c   | 20 ++++++++++----------
>  target-mips/op_helper.c |  8 ++++----
>  target-mips/translate.c |  5 +++--
>  4 files changed, 24 insertions(+), 23 deletions(-)
> 
> diff --git a/target-mips/cpu.h b/target-mips/cpu.h
> index 03eb888..2dfa139 100644
> --- a/target-mips/cpu.h
> +++ b/target-mips/cpu.h
> @@ -34,7 +34,7 @@ struct r4k_tlb_t {
>      uint_fast16_t RI0:1;
>      uint_fast16_t RI1:1;
>      uint_fast16_t EHINV:1;
> -    target_ulong PFN[2];
> +    uint64_t PFN[2];
>  };
>  
>  #if !defined(CONFIG_USER_ONLY)
> @@ -225,7 +225,7 @@ struct CPUMIPSState {
>      uint32_t SEGBITS;
>      uint32_t PABITS;
>      target_ulong SEGMask;
> -    target_ulong PAMask;
> +    uint64_t PAMask;
>  
>      int32_t msair;
>  #define MSAIR_ProcID    8
> @@ -273,8 +273,8 @@ struct CPUMIPSState {
>  #define CP0VPEOpt_DWX2	2
>  #define CP0VPEOpt_DWX1	1
>  #define CP0VPEOpt_DWX0	0
> -    target_ulong CP0_EntryLo0;
> -    target_ulong CP0_EntryLo1;
> +    uint64_t CP0_EntryLo0;
> +    uint64_t CP0_EntryLo1;

If you change the size of these registers, you have to adjust the
corresponding MFC0 function for MIPS32, as the tcg_gen_ld_tl() function
will point to the wrong side of the field on big endian hosts.

>  #if defined(TARGET_MIPS64)
>  # define CP0EnLo_RI 63
>  # define CP0EnLo_XI 62
> @@ -471,11 +471,11 @@ struct CPUMIPSState {
>      int32_t CP0_Config6;
>      int32_t CP0_Config7;
>      /* XXX: Maybe make LLAddr per-TC? */
> -    target_ulong lladdr;
> +    uint64_t lladdr;
>      target_ulong llval;
>      target_ulong llnewval;
>      target_ulong llreg;
> -    target_ulong CP0_LLAddr_rw_bitmask;
> +    uint64_t CP0_LLAddr_rw_bitmask;
>      int CP0_LLAddr_shift;
>      target_ulong CP0_WatchLo[8];
>      int32_t CP0_WatchHi[8];
> @@ -502,7 +502,7 @@ struct CPUMIPSState {
>  #define CP0DB_DSS  0
>      target_ulong CP0_DEPC;
>      int32_t CP0_Performance0;
> -    int32_t CP0_TagLo;
> +    uint64_t CP0_TagLo;
>      int32_t CP0_DataLo;
>      int32_t CP0_TagHi;
>      int32_t CP0_DataHi;
> diff --git a/target-mips/machine.c b/target-mips/machine.c
> index 7d1fa32..559402c 100644
> --- a/target-mips/machine.c
> +++ b/target-mips/machine.c
> @@ -142,8 +142,8 @@ static int get_tlb(QEMUFile *f, void *pv, size_t size)
>      v->RI0 = (flags >> 13) & 1;
>      v->XI1 = (flags >> 12) & 1;
>      v->XI0 = (flags >> 11) & 1;
> -    qemu_get_betls(f, &v->PFN[0]);
> -    qemu_get_betls(f, &v->PFN[1]);
> +    qemu_get_be64s(f, &v->PFN[0]);
> +    qemu_get_be64s(f, &v->PFN[1]);
>  
>      return 0;
>  }
> @@ -169,8 +169,8 @@ static void put_tlb(QEMUFile *f, void *pv, size_t size)
>      qemu_put_be32s(f, &v->PageMask);
>      qemu_put_8s(f, &v->ASID);
>      qemu_put_be16s(f, &flags);
> -    qemu_put_betls(f, &v->PFN[0]);
> -    qemu_put_betls(f, &v->PFN[1]);
> +    qemu_put_be64s(f, &v->PFN[0]);
> +    qemu_put_be64s(f, &v->PFN[1]);
>  }
>  
>  const VMStateInfo vmstate_info_tlb = {
> @@ -201,8 +201,8 @@ const VMStateDescription vmstate_tlb = {
>  
>  const VMStateDescription vmstate_mips_cpu = {
>      .name = "cpu",
> -    .version_id = 6,
> -    .minimum_version_id = 6,
> +    .version_id = 7,
> +    .minimum_version_id = 7,
>      .post_load = cpu_post_load,
>      .fields = (VMStateField[]) {
>          /* Active TC */
> @@ -237,8 +237,8 @@ const VMStateDescription vmstate_mips_cpu = {
>          VMSTATE_UINTTL(env.CP0_VPESchedule, MIPSCPU),
>          VMSTATE_UINTTL(env.CP0_VPEScheFBack, MIPSCPU),
>          VMSTATE_INT32(env.CP0_VPEOpt, MIPSCPU),
> -        VMSTATE_UINTTL(env.CP0_EntryLo0, MIPSCPU),
> -        VMSTATE_UINTTL(env.CP0_EntryLo1, MIPSCPU),
> +        VMSTATE_UINT64(env.CP0_EntryLo0, MIPSCPU),
> +        VMSTATE_UINT64(env.CP0_EntryLo1, MIPSCPU),
>          VMSTATE_UINTTL(env.CP0_Context, MIPSCPU),
>          VMSTATE_INT32(env.CP0_PageMask, MIPSCPU),
>          VMSTATE_INT32(env.CP0_PageGrain, MIPSCPU),
> @@ -269,7 +269,7 @@ const VMStateDescription vmstate_mips_cpu = {
>          VMSTATE_INT32(env.CP0_Config3, MIPSCPU),
>          VMSTATE_INT32(env.CP0_Config6, MIPSCPU),
>          VMSTATE_INT32(env.CP0_Config7, MIPSCPU),
> -        VMSTATE_UINTTL(env.lladdr, MIPSCPU),
> +        VMSTATE_UINT64(env.lladdr, MIPSCPU),
>          VMSTATE_UINTTL_ARRAY(env.CP0_WatchLo, MIPSCPU, 8),
>          VMSTATE_INT32_ARRAY(env.CP0_WatchHi, MIPSCPU, 8),
>          VMSTATE_UINTTL(env.CP0_XContext, MIPSCPU),
> @@ -277,7 +277,7 @@ const VMStateDescription vmstate_mips_cpu = {
>          VMSTATE_INT32(env.CP0_Debug, MIPSCPU),
>          VMSTATE_UINTTL(env.CP0_DEPC, MIPSCPU),
>          VMSTATE_INT32(env.CP0_Performance0, MIPSCPU),
> -        VMSTATE_INT32(env.CP0_TagLo, MIPSCPU),
> +        VMSTATE_UINT64(env.CP0_TagLo, MIPSCPU),
>          VMSTATE_INT32(env.CP0_DataLo, MIPSCPU),
>          VMSTATE_INT32(env.CP0_TagHi, MIPSCPU),
>          VMSTATE_INT32(env.CP0_DataHi, MIPSCPU),
> diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
> index 89ddad2..445c4b2 100644
> --- a/target-mips/op_helper.c
> +++ b/target-mips/op_helper.c
> @@ -1996,12 +1996,12 @@ void r4k_helper_tlbr(CPUMIPSState *env)
>          env->CP0_EntryHi = tlb->VPN | tlb->ASID;
>          env->CP0_PageMask = tlb->PageMask;
>          env->CP0_EntryLo0 = tlb->G | (tlb->V0 << 1) | (tlb->D0 << 2) |
> -                        ((target_ulong)tlb->RI0 << CP0EnLo_RI) |
> -                        ((target_ulong)tlb->XI0 << CP0EnLo_XI) |
> +                        ((uint64_t)tlb->RI0 << CP0EnLo_RI) |
> +                        ((uint64_t)tlb->XI0 << CP0EnLo_XI) |
>                          (tlb->C0 << 3) | (tlb->PFN[0] >> 6);
>          env->CP0_EntryLo1 = tlb->G | (tlb->V1 << 1) | (tlb->D1 << 2) |
> -                        ((target_ulong)tlb->RI1 << CP0EnLo_RI) |
> -                        ((target_ulong)tlb->XI1 << CP0EnLo_XI) |
> +                        ((uint64_t)tlb->RI1 << CP0EnLo_RI) |
> +                        ((uint64_t)tlb->XI1 << CP0EnLo_XI) |
>                          (tlb->C1 << 3) | (tlb->PFN[1] >> 6);
>      }
>  }
> diff --git a/target-mips/translate.c b/target-mips/translate.c
> index fe6bc16..94936d4 100644
> --- a/target-mips/translate.c
> +++ b/target-mips/translate.c
> @@ -19413,7 +19413,8 @@ void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
>  
>      cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
>                  env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
> -    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
> +    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
> +                PRIx64 "\n",
>                  env->CP0_Config0, env->CP0_Config1, env->lladdr);
>      cpu_fprintf(f, "    Config2 0x%08x Config3 0x%08x\n",
>                  env->CP0_Config2, env->CP0_Config3);
> @@ -19547,7 +19548,7 @@ void cpu_state_reset(CPUMIPSState *env)
>      }
>  #endif
>      env->PABITS = env->cpu_model->PABITS;
> -    env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
> +    env->PAMask = (1ULL << env->cpu_model->PABITS) - 1;
>      env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
>      env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
>      env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
> 

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

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

* Re: [Qemu-devel] [PATCH v2 1/7] target-mips: extend selected CP0 registers to 64-bits in MIPS32
  2015-06-04 22:14   ` Aurelien Jarno
@ 2015-06-05 19:48     ` Leon Alrae
  0 siblings, 0 replies; 10+ messages in thread
From: Leon Alrae @ 2015-06-05 19:48 UTC (permalink / raw)
  To: Aurelien Jarno; +Cc: james.hogan, qemu-devel

On 04/06/15 23:14, Aurelien Jarno wrote:
> If you change the size of these registers, you have to adjust the
> corresponding MFC0 function for MIPS32, as the tcg_gen_ld_tl() function
> will point to the wrong side of the field on big endian hosts.

I'll fix it, thanks for pointing this out.

Leon

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

end of thread, other threads:[~2015-06-05 19:48 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-03  9:32 [Qemu-devel] [PATCH v2 0/7] target-mips: add support for large physical addresses Leon Alrae
2015-06-03  9:32 ` [Qemu-devel] [PATCH v2 1/7] target-mips: extend selected CP0 registers to 64-bits in MIPS32 Leon Alrae
2015-06-04 22:14   ` Aurelien Jarno
2015-06-05 19:48     ` Leon Alrae
2015-06-03  9:32 ` [Qemu-devel] [PATCH v2 2/7] target-mips: support Page Frame Number Extension field Leon Alrae
2015-06-03  9:32 ` [Qemu-devel] [PATCH v2 3/7] target-mips: add CP0.PageGrain.ELPA support Leon Alrae
2015-06-03  9:32 ` [Qemu-devel] [PATCH v2 4/7] target-mips: add MTHC0 and MFHC0 instructions Leon Alrae
2015-06-03  9:32 ` [Qemu-devel] [PATCH v2 5/7] target-mips: correct MFC0 for CP0.EntryLo in MIPS64 Leon Alrae
2015-06-03  9:32 ` [Qemu-devel] [PATCH v2 6/7] target-mips: remove misleading comments in translate_init.c Leon Alrae
2015-06-03  9:32 ` [Qemu-devel] [PATCH v2 7/7] target-mips: enable XPA and LPA features Leon Alrae

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.