* [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).