From: Alexander Graf <agraf@suse.de>
To: qemu-devel@nongnu.org
Cc: blauwirbel@gmail.com, Alexander Graf <alex@csgraf.de>
Subject: [Qemu-devel] [PATCH 2/3] PPC64: Implement slbmte
Date: Mon, 2 Mar 2009 18:07:53 +0100 [thread overview]
Message-ID: <1236013674-28082-3-git-send-email-agraf@suse.de> (raw)
In-Reply-To: <1236013674-28082-2-git-send-email-agraf@suse.de>
In order to modify SLB entries on recent PPC64 machines, the slbmte
instruction is used.
This patch implements the slbmte instruction and makes the "bridge"
mode code use the slb set functions, so we can move the SLB into
the CPU struct later.
This is required for Linux to run on PPC64.
Signed-off-by: Alexander Graf <alex@csgraf.de>
---
target-ppc/cpu.h | 3 +-
target-ppc/helper.c | 57 ++++++++++++++++++++++++++++++++++++-----------
target-ppc/op_helper.c | 6 +++-
target-ppc/translate.c | 23 ++++++++++++++++---
4 files changed, 68 insertions(+), 21 deletions(-)
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 80ee76c..67a0731 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -714,7 +714,8 @@ void ppc_store_sdr1 (CPUPPCState *env, target_ulong value);
#if defined(TARGET_PPC64)
void ppc_store_asr (CPUPPCState *env, target_ulong value);
target_ulong ppc_load_slb (CPUPPCState *env, int slb_nr);
-void ppc_store_slb (CPUPPCState *env, int slb_nr, target_ulong rs);
+target_ulong ppc_load_sr (CPUPPCState *env, int sr_nr);
+void ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs);
#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 e02dcb0..9461daf 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -821,27 +821,34 @@ target_ulong ppc_load_slb (CPUPPCState *env, int slb_nr)
return rt;
}
-void ppc_store_slb (CPUPPCState *env, int slb_nr, target_ulong rs)
+void ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs)
{
target_phys_addr_t sr_base;
uint64_t tmp64;
uint32_t tmp;
+ uint64_t vsid;
+ uint64_t esid;
+ int flags, valid, slb_nr;
+
+ vsid = rs >> 12;
+ flags = ((rs >> 8) & 0xf);
+
+ esid = rb >> 28;
+ valid = (rb & (1 << 27));
+ slb_nr = rb & 0xfff;
+
+ tmp64 = (esid << 28) | valid | (vsid >> 24);
+ tmp = (vsid << 8) | (flags << 3);
+
+ /* Write SLB entry to memory */
sr_base = env->spr[SPR_ASR];
sr_base += 12 * slb_nr;
- /* Copy Rs bits 37:63 to SLB 62:88 */
- tmp = rs << 8;
- tmp64 = (rs >> 24) & 0x7;
- /* Copy Rs bits 33:36 to SLB 89:92 */
- tmp |= ((rs >> 27) & 0xF) << 4;
- /* Set the valid bit */
- tmp64 |= 1 << 27;
- /* Set ESID */
- tmp64 |= (uint32_t)slb_nr << 28;
- LOG_SLB("%s: %d " ADDRX " => " PADDRX " %016" PRIx64
+
+ LOG_SLB("%s: %d " ADDRX " - " ADDRX " => " PADDRX " %016" PRIx64
" %08" PRIx32 "\n", __func__,
- slb_nr, rs, sr_base, tmp64, tmp);
- /* Write SLB entry to memory */
+ slb_nr, rb, rs, sr_base, tmp64, tmp);
+
stq_phys(sr_base, tmp64);
stl_phys(sr_base + 8, tmp);
}
@@ -1945,11 +1952,33 @@ void ppc_store_sdr1 (CPUPPCState *env, target_ulong value)
}
}
+target_ulong ppc_load_sr (CPUPPCState *env, int slb_nr)
+{
+ // XXX
+ return 0;
+}
+
void ppc_store_sr (CPUPPCState *env, int srnum, target_ulong value)
{
LOG_MMU("%s: reg=%d " ADDRX " " ADDRX "\n",
__func__, srnum, value, env->sr[srnum]);
- if (env->sr[srnum] != value) {
+ if (env->mmu_model & POWERPC_MMU_64) {
+ uint64_t rb = 0, rs = 0;
+
+ /* ESID = srnum */
+ rb |= ((uint32_t)srnum & 0xf) << 28;
+ /* Set the valid bit */
+ rb |= 1 << 27;
+ /* Index = ESID */
+ rb |= (uint32_t)srnum;
+
+ /* VSID = VSID */
+ rs |= (value & 0xfffffff) << 12;
+ /* flags = flags */
+ rs |= ((value >> 27) & 0xf) << 9;
+
+ ppc_store_slb(env, rb, rs);
+ } else if (env->sr[srnum] != value) {
env->sr[srnum] = value;
#if !defined(FLUSH_ALL_TLBS) && 0
{
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index 3afd217..527f8de 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -3752,6 +3752,8 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
/* Segment registers load and store */
target_ulong helper_load_sr (target_ulong sr_num)
{
+ if (env->mmu_model & POWERPC_MMU_64)
+ return ppc_load_sr(env, sr_num);
return env->sr[sr_num];
}
@@ -3767,9 +3769,9 @@ target_ulong helper_load_slb (target_ulong slb_nr)
return ppc_load_slb(env, slb_nr);
}
-void helper_store_slb (target_ulong slb_nr, target_ulong rs)
+void helper_store_slb (target_ulong rb, target_ulong rs)
{
- ppc_store_slb(env, slb_nr, rs);
+ ppc_store_slb(env, rb, rs);
}
void helper_slbia (void)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 2e7420f..d544c8a 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -4291,7 +4291,7 @@ GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B)
return;
}
t0 = tcg_const_tl(SR(ctx->opcode));
- gen_helper_load_slb(cpu_gpr[rD(ctx->opcode)], t0);
+ gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
tcg_temp_free(t0);
#endif
}
@@ -4311,7 +4311,7 @@ GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
t0 = tcg_temp_new();
tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
tcg_gen_andi_tl(t0, t0, 0xF);
- gen_helper_load_slb(cpu_gpr[rD(ctx->opcode)], t0);
+ gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
tcg_temp_free(t0);
#endif
}
@@ -4328,7 +4328,7 @@ GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B)
return;
}
t0 = tcg_const_tl(SR(ctx->opcode));
- gen_helper_store_slb(t0, cpu_gpr[rS(ctx->opcode)]);
+ gen_helper_store_sr(t0, cpu_gpr[rS(ctx->opcode)]);
tcg_temp_free(t0);
#endif
}
@@ -4348,10 +4348,25 @@ GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
t0 = tcg_temp_new();
tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
tcg_gen_andi_tl(t0, t0, 0xF);
- gen_helper_store_slb(t0, cpu_gpr[rS(ctx->opcode)]);
+ gen_helper_store_sr(t0, cpu_gpr[rS(ctx->opcode)]);
tcg_temp_free(t0);
#endif
}
+
+/* slbmte */
+GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x00000000, PPC_SEGMENT_64B)
+{
+#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_store_slb(cpu_gpr[rB(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
+#endif
+}
+
#endif /* defined(TARGET_PPC64) */
/*** Lookaside buffer management ***/
--
1.6.0.2
next prev parent reply other threads:[~2009-03-02 17:08 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-03-02 17:07 [Qemu-devel] [PATCH 0/3] PPC64 Linux bringup patches Alexander Graf
2009-03-02 17:07 ` [Qemu-devel] [PATCH 1/3] PPC: Circumvent overflow in mtcrf Alexander Graf
2009-03-02 17:07 ` Alexander Graf [this message]
2009-03-02 17:07 ` [Qemu-devel] [PATCH 3/3] PPC64: Implement large pages Alexander Graf
2009-03-02 18:58 ` [Qemu-devel] Re: [PATCH 2/3] PPC64: Implement slbmte Blue Swirl
2009-03-02 19:00 ` Alexander Graf
2009-03-02 19:07 ` Paul Brook
2009-03-02 19:28 ` Blue Swirl
2009-03-02 19:47 ` Alexander Graf
2009-03-02 18:53 ` [Qemu-devel] Re: [PATCH 1/3] PPC: Circumvent overflow in mtcrf Blue Swirl
2009-03-02 22:45 ` [Qemu-devel] " Laurent Desnogues
2009-03-03 10:26 ` Alexander Graf
2009-03-03 10:30 ` Laurent Desnogues
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1236013674-28082-3-git-send-email-agraf@suse.de \
--to=agraf@suse.de \
--cc=alex@csgraf.de \
--cc=blauwirbel@gmail.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).