summaryrefslogtreecommitdiffstats
path: root/target/hppa/mem_helper.c
diff options
context:
space:
mode:
authorRichard Henderson2017-10-27 18:33:23 +0200
committerRichard Henderson2018-01-30 19:22:26 +0100
commit63300a00ab52c770f8a76218d4a3a75e0db8a6d0 (patch)
treec1e3d56a2cecf0aec0d2d6d736c5b2cfc487788a /target/hppa/mem_helper.c
parenttarget/hppa: Implement I*TLBA and I*TLBP insns (diff)
downloadqemu-63300a00ab52c770f8a76218d4a3a75e0db8a6d0.tar.gz
qemu-63300a00ab52c770f8a76218d4a3a75e0db8a6d0.tar.xz
qemu-63300a00ab52c770f8a76218d4a3a75e0db8a6d0.zip
target/hppa: Implement P*TLB and P*TLBE insns
We now have all of the TLB manipulation instructions. Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target/hppa/mem_helper.c')
-rw-r--r--target/hppa/mem_helper.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index 59619e9ba8..995b1937f6 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -277,4 +277,41 @@ void HELPER(itlbp)(CPUHPPAState *env, target_ulong addr, target_ureg reg)
ent->t = extract32(reg, 29, 1);
ent->entry_valid = 1;
}
+
+/* Purge (Insn/Data) TLB. This is explicitly page-based, and is
+ synchronous across all processors. */
+static void ptlb_work(CPUState *cpu, run_on_cpu_data data)
+{
+ CPUHPPAState *env = cpu->env_ptr;
+ target_ulong addr = (target_ulong) data.target_ptr;
+ hppa_tlb_entry *ent = hppa_find_tlb(env, addr);
+
+ if (ent && ent->entry_valid) {
+ hppa_flush_tlb_ent(env, ent);
+ }
+}
+
+void HELPER(ptlb)(CPUHPPAState *env, target_ulong addr)
+{
+ CPUState *src = CPU(hppa_env_get_cpu(env));
+ CPUState *cpu;
+ run_on_cpu_data data = RUN_ON_CPU_TARGET_PTR(addr);
+
+ CPU_FOREACH(cpu) {
+ if (cpu != src) {
+ async_run_on_cpu(cpu, ptlb_work, data);
+ }
+ }
+ async_safe_run_on_cpu(src, ptlb_work, data);
+}
+
+/* Purge (Insn/Data) TLB entry. This affects an implementation-defined
+ number of pages/entries (we choose all), and is local to the cpu. */
+void HELPER(ptlbe)(CPUHPPAState *env)
+{
+ CPUState *src = CPU(hppa_env_get_cpu(env));
+
+ memset(env->tlb, 0, sizeof(env->tlb));
+ tlb_flush_by_mmuidx(src, 0xf);
+}
#endif /* CONFIG_USER_ONLY */