aboutsummaryrefslogtreecommitdiff
path: root/target/ppc
diff options
context:
space:
mode:
authorSuraj Jitindar Singh <sjitindarsingh@gmail.com>2019-11-28 14:46:54 +0100
committerDavid Gibson <david@gibson.dropbear.id.au>2019-12-17 10:39:48 +1100
commit5d62725b2fefd59abf7225d620f7092fd34b8e11 (patch)
treeea19cd6b909fdbadccafe83f993120d096668aed /target/ppc
parent2661f6ab2ba1694d7c19efdd622378817cb874ea (diff)
downloadqemu-5d62725b2fefd59abf7225d620f7092fd34b8e11.zip
qemu-5d62725b2fefd59abf7225d620f7092fd34b8e11.tar.gz
qemu-5d62725b2fefd59abf7225d620f7092fd34b8e11.tar.bz2
target/ppc: Implement the VTB for HV access
The virtual timebase register (VTB) is a 64-bit register which increments at the same rate as the timebase register, present on POWER8 and later processors. The register is able to be read/written by the hypervisor and read by the supervisor. All other accesses are illegal. Currently the VTB is just an alias for the timebase (TB) register. Implement the VTB so that is can be read/written independent of the TB. Make use of the existing method for accessing timebase facilities where by the compensation is stored and used to compute the value on reads/is updated on writes. Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com> [ clg: rebased on current ppc tree ] Signed-off-by: Cédric Le Goater <clg@kaod.org> Message-Id: <20191128134700.16091-2-clg@kaod.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'target/ppc')
-rw-r--r--target/ppc/cpu.h2
-rw-r--r--target/ppc/helper.h2
-rw-r--r--target/ppc/timebase_helper.c10
-rw-r--r--target/ppc/translate_init.inc.c19
4 files changed, 29 insertions, 4 deletions
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index fbec1b0..eb7d2c7 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1303,6 +1303,8 @@ uint64_t cpu_ppc_load_atbl(CPUPPCState *env);
uint32_t cpu_ppc_load_atbu(CPUPPCState *env);
void cpu_ppc_store_atbl(CPUPPCState *env, uint32_t value);
void cpu_ppc_store_atbu(CPUPPCState *env, uint32_t value);
+uint64_t cpu_ppc_load_vtb(CPUPPCState *env);
+void cpu_ppc_store_vtb(CPUPPCState *env, uint64_t value);
bool ppc_decr_clear_on_delivery(CPUPPCState *env);
target_ulong cpu_ppc_load_decr(CPUPPCState *env);
void cpu_ppc_store_decr(CPUPPCState *env, target_ulong value);
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index f843814..a5f53bb 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -649,6 +649,7 @@ DEF_HELPER_FLAGS_1(load_tbl, TCG_CALL_NO_RWG, tl, env)
DEF_HELPER_FLAGS_1(load_tbu, TCG_CALL_NO_RWG, tl, env)
DEF_HELPER_FLAGS_1(load_atbl, TCG_CALL_NO_RWG, tl, env)
DEF_HELPER_FLAGS_1(load_atbu, TCG_CALL_NO_RWG, tl, env)
+DEF_HELPER_FLAGS_1(load_vtb, TCG_CALL_NO_RWG, tl, env)
DEF_HELPER_FLAGS_1(load_601_rtcl, TCG_CALL_NO_RWG, tl, env)
DEF_HELPER_FLAGS_1(load_601_rtcu, TCG_CALL_NO_RWG, tl, env)
#if !defined(CONFIG_USER_ONLY)
@@ -669,6 +670,7 @@ DEF_HELPER_FLAGS_1(load_decr, TCG_CALL_NO_RWG, tl, env)
DEF_HELPER_FLAGS_2(store_decr, TCG_CALL_NO_RWG, void, env, tl)
DEF_HELPER_FLAGS_1(load_hdecr, TCG_CALL_NO_RWG, tl, env)
DEF_HELPER_FLAGS_2(store_hdecr, TCG_CALL_NO_RWG, void, env, tl)
+DEF_HELPER_FLAGS_2(store_vtb, TCG_CALL_NO_RWG, void, env, tl)
DEF_HELPER_2(store_hid0_601, void, env, tl)
DEF_HELPER_3(store_403_pbr, void, env, i32, tl)
DEF_HELPER_FLAGS_1(load_40x_pit, TCG_CALL_NO_RWG, tl, env)
diff --git a/target/ppc/timebase_helper.c b/target/ppc/timebase_helper.c
index 73363e0..8c3c2fe 100644
--- a/target/ppc/timebase_helper.c
+++ b/target/ppc/timebase_helper.c
@@ -45,6 +45,11 @@ target_ulong helper_load_atbu(CPUPPCState *env)
return cpu_ppc_load_atbu(env);
}
+target_ulong helper_load_vtb(CPUPPCState *env)
+{
+ return cpu_ppc_load_vtb(env);
+}
+
#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
target_ulong helper_load_purr(CPUPPCState *env)
{
@@ -113,6 +118,11 @@ void helper_store_hdecr(CPUPPCState *env, target_ulong val)
cpu_ppc_store_hdecr(env, val);
}
+void helper_store_vtb(CPUPPCState *env, target_ulong val)
+{
+ cpu_ppc_store_vtb(env, val);
+}
+
target_ulong helper_load_40x_pit(CPUPPCState *env)
{
return load_40x_pit(env);
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index 7364d36..226aecf 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -312,6 +312,16 @@ static void spr_write_hdecr(DisasContext *ctx, int sprn, int gprn)
}
}
+static void spr_read_vtb(DisasContext *ctx, int gprn, int sprn)
+{
+ gen_helper_load_vtb(cpu_gpr[gprn], cpu_env);
+}
+
+static void spr_write_vtb(DisasContext *ctx, int sprn, int gprn)
+{
+ gen_helper_store_vtb(cpu_env, cpu_gpr[gprn]);
+}
+
#endif
#endif
@@ -8174,10 +8184,11 @@ static void gen_spr_power8_ebb(CPUPPCState *env)
/* Virtual Time Base */
static void gen_spr_vtb(CPUPPCState *env)
{
- spr_register_kvm(env, SPR_VTB, "VTB",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_tbl, SPR_NOACCESS,
- KVM_REG_PPC_VTB, 0x00000000);
+ spr_register_kvm_hv(env, SPR_VTB, "VTB",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_vtb, SPR_NOACCESS,
+ &spr_read_vtb, &spr_write_vtb,
+ KVM_REG_PPC_VTB, 0x00000000);
}
static void gen_spr_power8_fscr(CPUPPCState *env)