mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-11 03:24:58 -06:00
ppc: Use a helper to filter writes to LPCR
This handles filtering bits based on what is implemented by a given architecture version. We also use it to copy to LPCR some of the relevant 970 HID4 bits. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> [clg: fixed checkpatch.pl errors ] Signed-off-by: Cédric Le Goater <clg@kaod.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
88536935c0
commit
4b3fc37788
3 changed files with 95 additions and 19 deletions
|
@ -16,6 +16,7 @@ DEF_HELPER_1(rfmci, void, env)
|
||||||
DEF_HELPER_2(pminsn, void, env, i32)
|
DEF_HELPER_2(pminsn, void, env, i32)
|
||||||
DEF_HELPER_1(rfid, void, env)
|
DEF_HELPER_1(rfid, void, env)
|
||||||
DEF_HELPER_1(hrfid, void, env)
|
DEF_HELPER_1(hrfid, void, env)
|
||||||
|
DEF_HELPER_2(store_lpcr, void, env, tl)
|
||||||
#endif
|
#endif
|
||||||
DEF_HELPER_1(check_tlb_flush, void, env)
|
DEF_HELPER_1(check_tlb_flush, void, env)
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -851,3 +851,60 @@ void ppc_hash64_tlb_flush_hpte(PowerPCCPU *cpu,
|
||||||
*/
|
*/
|
||||||
tlb_flush(CPU(cpu), 1);
|
tlb_flush(CPU(cpu), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void helper_store_lpcr(CPUPPCState *env, target_ulong val)
|
||||||
|
{
|
||||||
|
uint64_t lpcr = 0;
|
||||||
|
|
||||||
|
/* Filter out bits */
|
||||||
|
switch (env->mmu_model) {
|
||||||
|
case POWERPC_MMU_64B: /* 970 */
|
||||||
|
if (val & 0x40) {
|
||||||
|
lpcr |= LPCR_LPES0;
|
||||||
|
}
|
||||||
|
if (val & 0x8000000000000000ull) {
|
||||||
|
lpcr |= LPCR_LPES1;
|
||||||
|
}
|
||||||
|
if (val & 0x20) {
|
||||||
|
lpcr |= (0x4ull << LPCR_RMLS_SHIFT);
|
||||||
|
}
|
||||||
|
if (val & 0x4000000000000000ull) {
|
||||||
|
lpcr |= (0x2ull << LPCR_RMLS_SHIFT);
|
||||||
|
}
|
||||||
|
if (val & 0x2000000000000000ull) {
|
||||||
|
lpcr |= (0x1ull << LPCR_RMLS_SHIFT);
|
||||||
|
}
|
||||||
|
env->spr[SPR_RMOR] = ((lpcr >> 41) & 0xffffull) << 26;
|
||||||
|
|
||||||
|
/* XXX We could also write LPID from HID4 here
|
||||||
|
* but since we don't tag any translation on it
|
||||||
|
* it doesn't actually matter
|
||||||
|
*/
|
||||||
|
/* XXX For proper emulation of 970 we also need
|
||||||
|
* to dig HRMOR out of HID5
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
case POWERPC_MMU_2_03: /* P5p */
|
||||||
|
lpcr = val & (LPCR_RMLS | LPCR_ILE |
|
||||||
|
LPCR_LPES0 | LPCR_LPES1 |
|
||||||
|
LPCR_RMI | LPCR_HDICE);
|
||||||
|
break;
|
||||||
|
case POWERPC_MMU_2_06: /* P7 */
|
||||||
|
lpcr = val & (LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_DPFD |
|
||||||
|
LPCR_VRMASD | LPCR_RMLS | LPCR_ILE |
|
||||||
|
LPCR_P7_PECE0 | LPCR_P7_PECE1 | LPCR_P7_PECE2 |
|
||||||
|
LPCR_MER | LPCR_TC |
|
||||||
|
LPCR_LPES0 | LPCR_LPES1 | LPCR_HDICE);
|
||||||
|
break;
|
||||||
|
case POWERPC_MMU_2_07: /* P8 */
|
||||||
|
lpcr = val & (LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV |
|
||||||
|
LPCR_DPFD | LPCR_VRMASD | LPCR_RMLS | LPCR_ILE |
|
||||||
|
LPCR_AIL | LPCR_ONL | LPCR_P8_PECE0 | LPCR_P8_PECE1 |
|
||||||
|
LPCR_P8_PECE2 | LPCR_P8_PECE3 | LPCR_P8_PECE4 |
|
||||||
|
LPCR_MER | LPCR_TC | LPCR_LPES0 | LPCR_HDICE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
env->spr[SPR_LPCR] = lpcr;
|
||||||
|
}
|
||||||
|
|
|
@ -7525,16 +7525,6 @@ static void gen_spr_970_hior(CPUPPCState *env)
|
||||||
0x00000000);
|
0x00000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen_spr_970_lpar(CPUPPCState *env)
|
|
||||||
{
|
|
||||||
/* Logical partitionning */
|
|
||||||
/* PPC970: HID4 is effectively the LPCR */
|
|
||||||
spr_register(env, SPR_970_HID4, "HID4",
|
|
||||||
SPR_NOACCESS, SPR_NOACCESS,
|
|
||||||
&spr_read_generic, &spr_write_generic,
|
|
||||||
0x00000000);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void gen_spr_book3s_common(CPUPPCState *env)
|
static void gen_spr_book3s_common(CPUPPCState *env)
|
||||||
{
|
{
|
||||||
spr_register(env, SPR_CTRL, "SPR_CTRL",
|
spr_register(env, SPR_CTRL, "SPR_CTRL",
|
||||||
|
@ -7787,15 +7777,6 @@ static void gen_spr_power5p_ear(CPUPPCState *env)
|
||||||
0x00000000);
|
0x00000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen_spr_power5p_lpar(CPUPPCState *env)
|
|
||||||
{
|
|
||||||
/* Logical partitionning */
|
|
||||||
spr_register_kvm(env, SPR_LPCR, "LPCR",
|
|
||||||
SPR_NOACCESS, SPR_NOACCESS,
|
|
||||||
&spr_read_generic, &spr_write_generic,
|
|
||||||
KVM_REG_PPC_LPCR, LPCR_LPES0 | LPCR_LPES1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
static void spr_write_hmer(DisasContext *ctx, int sprn, int gprn)
|
static void spr_write_hmer(DisasContext *ctx, int sprn, int gprn)
|
||||||
{
|
{
|
||||||
|
@ -7807,7 +7788,44 @@ static void spr_write_hmer(DisasContext *ctx, int sprn, int gprn)
|
||||||
spr_store_dump_spr(sprn);
|
spr_store_dump_spr(sprn);
|
||||||
tcg_temp_free(hmer);
|
tcg_temp_free(hmer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void spr_write_lpcr(DisasContext *ctx, int sprn, int gprn)
|
||||||
|
{
|
||||||
|
gen_helper_store_lpcr(cpu_env, cpu_gpr[gprn]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void spr_write_970_hid4(DisasContext *ctx, int sprn, int gprn)
|
||||||
|
{
|
||||||
|
#if defined(TARGET_PPC64)
|
||||||
|
spr_write_generic(ctx, sprn, gprn);
|
||||||
|
gen_helper_store_lpcr(cpu_env, cpu_gpr[gprn]);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* !defined(CONFIG_USER_ONLY) */
|
||||||
|
|
||||||
|
static void gen_spr_970_lpar(CPUPPCState *env)
|
||||||
|
{
|
||||||
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
|
/* Logical partitionning */
|
||||||
|
/* PPC970: HID4 is effectively the LPCR */
|
||||||
|
spr_register(env, SPR_970_HID4, "HID4",
|
||||||
|
SPR_NOACCESS, SPR_NOACCESS,
|
||||||
|
&spr_read_generic, &spr_write_970_hid4,
|
||||||
|
0x00000000);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gen_spr_power5p_lpar(CPUPPCState *env)
|
||||||
|
{
|
||||||
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
|
/* Logical partitionning */
|
||||||
|
spr_register_kvm(env, SPR_LPCR, "LPCR",
|
||||||
|
SPR_NOACCESS, SPR_NOACCESS,
|
||||||
|
&spr_read_generic, &spr_write_lpcr,
|
||||||
|
KVM_REG_PPC_LPCR, LPCR_LPES0 | LPCR_LPES1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void gen_spr_book3s_ids(CPUPPCState *env)
|
static void gen_spr_book3s_ids(CPUPPCState *env)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue