qemu-devel.nongnu.org archive mirror
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).