[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 04/27] Implement PowerPC slbmfee and slbmfev instruc
From: |
David Gibson |
Subject: |
[Qemu-devel] [PATCH 04/27] Implement PowerPC slbmfee and slbmfev instructions |
Date: |
Fri, 25 Mar 2011 14:21:09 +1100 |
For a 64-bit PowerPC target, qemu correctly implements translation
through the segment lookaside buffer. Likewise it supports the
slbmte instruction which is used to load entries into the SLB.
However, it does not emulate the slbmfee and slbmfev instructions
which read SLB entries back into registers. Because these are
only occasionally used in guests (mostly for debugging) we get
away with it.
However, given the recent SLB cleanups, it becomes quite easy to
implement these, and thereby allow, amongst other things, a guest
Linux to use xmon's command to dump the SLB.
Signed-off-by: David Gibson <address@hidden>
---
target-ppc/cpu.h | 2 ++
target-ppc/helper.c | 26 ++++++++++++++++++++++++++
target-ppc/helper.h | 2 ++
target-ppc/op_helper.c | 20 ++++++++++++++++++++
target-ppc/translate.c | 31 ++++++++++++++++++++++++++++++-
5 files changed, 80 insertions(+), 1 deletions(-)
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 36ca342..f293f85 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -779,6 +779,8 @@ void ppc_store_asr (CPUPPCState *env, target_ulong value);
target_ulong ppc_load_slb (CPUPPCState *env, int slb_nr);
target_ulong ppc_load_sr (CPUPPCState *env, int sr_nr);
int ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs);
+int ppc_load_slb_esid (CPUPPCState *env, target_ulong rb, target_ulong *rt);
+int ppc_load_slb_vsid (CPUPPCState *env, target_ulong rb, target_ulong *rt);
#endif /* defined(TARGET_PPC64) */
void ppc_store_sr (CPUPPCState *env, int srnum, target_ulong value);
#endif /* !defined(CONFIG_USER_ONLY) */
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 452a35c..b9621d2 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -774,6 +774,32 @@ int ppc_store_slb (CPUPPCState *env, target_ulong rb,
target_ulong rs)
return 0;
}
+
+int ppc_load_slb_esid (CPUPPCState *env, target_ulong rb, target_ulong *rt)
+{
+ int slot = rb & 0xfff;
+ ppc_slb_t *slb = &env->slb[slot];
+
+ if (slot >= env->slb_nr) {
+ return -1;
+ }
+
+ *rt = slb->esid;
+ return 0;
+}
+
+int ppc_load_slb_vsid (CPUPPCState *env, target_ulong rb, target_ulong *rt)
+{
+ int slot = rb & 0xfff;
+ ppc_slb_t *slb = &env->slb[slot];
+
+ if (slot >= env->slb_nr) {
+ return -1;
+ }
+
+ *rt = slb->vsid;
+ return 0;
+}
#endif /* defined(TARGET_PPC64) */
/* Perform segment based translation */
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index d512cb0..1a69cf8 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -341,6 +341,8 @@ DEF_HELPER_FLAGS_0(tlbia, TCG_CALL_CONST, void)
DEF_HELPER_FLAGS_1(tlbie, TCG_CALL_CONST, void, tl)
#if defined(TARGET_PPC64)
DEF_HELPER_FLAGS_2(store_slb, TCG_CALL_CONST, void, tl, tl)
+DEF_HELPER_1(load_slb_esid, tl, tl)
+DEF_HELPER_1(load_slb_vsid, tl, tl)
DEF_HELPER_FLAGS_0(slbia, TCG_CALL_CONST, void)
DEF_HELPER_FLAGS_1(slbie, TCG_CALL_CONST, void, tl)
#endif
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index bf41627..bdb1f17 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -3753,6 +3753,26 @@ void helper_store_slb (target_ulong rb, target_ulong rs)
}
}
+target_ulong helper_load_slb_esid (target_ulong rb)
+{
+ target_ulong rt;
+
+ if (ppc_load_slb_esid(env, rb, &rt) < 0) {
+ helper_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL);
+ }
+ return rt;
+}
+
+target_ulong helper_load_slb_vsid (target_ulong rb)
+{
+ target_ulong rt;
+
+ if (ppc_load_slb_vsid(env, rb, &rt) < 0) {
+ helper_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL);
+ }
+ return rt;
+}
+
void helper_slbia (void)
{
ppc_slb_invalidate_all(env);
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 3d265e3..0b6bfe7 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -4227,6 +4227,33 @@ static void gen_slbmte(DisasContext *ctx)
#endif
}
+static void gen_slbmfee(DisasContext *ctx)
+{
+#if defined(CONFIG_USER_ONLY)
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+#else
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+ return;
+ }
+ gen_helper_load_slb_esid(cpu_gpr[rS(ctx->opcode)],
+ cpu_gpr[rB(ctx->opcode)]);
+#endif
+}
+
+static void gen_slbmfev(DisasContext *ctx)
+{
+#if defined(CONFIG_USER_ONLY)
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+#else
+ if (unlikely(!ctx->mem_idx)) {
+ gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+ return;
+ }
+ gen_helper_load_slb_vsid(cpu_gpr[rS(ctx->opcode)],
+ cpu_gpr[rB(ctx->opcode)]);
+#endif
+}
#endif /* defined(TARGET_PPC64) */
/*** Lookaside buffer management ***/
@@ -8300,7 +8327,9 @@ GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14,
0x001F0001,
GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B),
GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
PPC_SEGMENT_64B),
-GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x00000000, PPC_SEGMENT_64B),
+GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x001F0001, PPC_SEGMENT_64B),
+GEN_HANDLER2(slbmfee, "slbmfee", 0x1F, 0x13, 0x1C, 0x001F0001,
PPC_SEGMENT_64B),
+GEN_HANDLER2(slbmfev, "slbmfev", 0x1F, 0x13, 0x1A, 0x001F0001,
PPC_SEGMENT_64B),
#endif
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA),
GEN_HANDLER(tlbiel, 0x1F, 0x12, 0x08, 0x03FF0001, PPC_MEM_TLBIE),
--
1.7.1
- [Qemu-devel] [0/27] Implement emulation of pSeries logical partitions (v5), David Gibson, 2011/03/24
- [Qemu-devel] [PATCH 01/27] Clean up PowerPC SLB handling code, David Gibson, 2011/03/24
- [Qemu-devel] [PATCH 03/27] Add a hook to allow hypercalls to be emulated on PowerPC, David Gibson, 2011/03/24
- [Qemu-devel] [PATCH 05/27] Implement missing parts of the logic for the POWER PURR, David Gibson, 2011/03/24
- [Qemu-devel] [PATCH 06/27] Correct ppc popcntb logic, implement popcntw and popcntd, David Gibson, 2011/03/24
- [Qemu-devel] [PATCH 07/27] Clean up slb_lookup() function, David Gibson, 2011/03/24
- [Qemu-devel] [PATCH 08/27] Parse SDR1 on mtspr instead of at translate time, David Gibson, 2011/03/24
- [Qemu-devel] [PATCH 04/27] Implement PowerPC slbmfee and slbmfev instructions,
David Gibson <=
- [Qemu-devel] [PATCH 10/27] Better factor the ppc hash translation path, David Gibson, 2011/03/24
- [Qemu-devel] [PATCH 09/27] Use "hash" more consistently in ppc mmu code, David Gibson, 2011/03/24
- [Qemu-devel] [PATCH 11/27] Support 1T segments on ppc, David Gibson, 2011/03/24
- [Qemu-devel] [PATCH 12/27] Add POWER7 support for ppc, David Gibson, 2011/03/24
- [Qemu-devel] [PATCH 02/27] Allow qemu_devtree_setprop() to take arbitrary values, David Gibson, 2011/03/24
- [Qemu-devel] [PATCH 13/27] Start implementing pSeries logical partition machine, David Gibson, 2011/03/24
- [Qemu-devel] [PATCH 14/27] Implement the bus structure for PAPR virtual IO, David Gibson, 2011/03/24
- [Qemu-devel] [PATCH 16/27] Implement hcall based RTAS for pSeries machines, David Gibson, 2011/03/24
- [Qemu-devel] [PATCH 20/27] Add (virtual) interrupt to PAPR virtual tty device, David Gibson, 2011/03/24
- [Qemu-devel] [PATCH 19/27] Add PAPR H_VIO_SIGNAL hypercall and infrastructure for VIO interrupts, David Gibson, 2011/03/24