summaryrefslogtreecommitdiff
path: root/meta-arm/meta-arm-bsp/recipes-bsp/hafnium/files/tc/0001-feat-emulate-cntp-timer-register-accesses-using-cnth.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-arm/meta-arm-bsp/recipes-bsp/hafnium/files/tc/0001-feat-emulate-cntp-timer-register-accesses-using-cnth.patch')
-rw-r--r--meta-arm/meta-arm-bsp/recipes-bsp/hafnium/files/tc/0001-feat-emulate-cntp-timer-register-accesses-using-cnth.patch252
1 files changed, 252 insertions, 0 deletions
diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/hafnium/files/tc/0001-feat-emulate-cntp-timer-register-accesses-using-cnth.patch b/meta-arm/meta-arm-bsp/recipes-bsp/hafnium/files/tc/0001-feat-emulate-cntp-timer-register-accesses-using-cnth.patch
new file mode 100644
index 0000000000..7094c8bc8f
--- /dev/null
+++ b/meta-arm/meta-arm-bsp/recipes-bsp/hafnium/files/tc/0001-feat-emulate-cntp-timer-register-accesses-using-cnth.patch
@@ -0,0 +1,252 @@
+From c8bd941579fb062359b683b184b851eea2ddb761 Mon Sep 17 00:00:00 2001
+From: Ben Horgan <ben.horgan@arm.com>
+Date: Fri, 4 Mar 2022 16:48:14 +0000
+Subject: [PATCH 1/5] feat: emulate cntp timer register accesses using cnthps
+
+Upstream-Status: Inappropriate [Experimental feature]
+Signed-off-by: Ben Horgan <ben.horgan@arm.com>
+Change-Id: I67508203273baf3bd8e6be2d99717028db945715
+---
+ Makefile | 3 +-
+ src/arch/aarch64/hypervisor/BUILD.gn | 1 +
+ src/arch/aarch64/hypervisor/cpu.c | 11 ++-
+ src/arch/aarch64/hypervisor/handler.c | 6 ++
+ src/arch/aarch64/hypervisor/timer_el1.c | 104 ++++++++++++++++++++++++
+ src/arch/aarch64/hypervisor/timer_el1.h | 20 +++++
+ src/arch/aarch64/msr.h | 8 ++
+ 7 files changed, 150 insertions(+), 3 deletions(-)
+ create mode 100644 src/arch/aarch64/hypervisor/timer_el1.c
+ create mode 100644 src/arch/aarch64/hypervisor/timer_el1.h
+
+diff --git a/Makefile b/Makefile
+index c9fb16f..6371a8a 100644
+--- a/Makefile
++++ b/Makefile
+@@ -59,7 +59,8 @@ CHECKPATCH := $(CURDIR)/third_party/linux/scripts/checkpatch.pl \
+ # debug_el1.c : uses XMACROS, which checkpatch doesn't understand.
+ # perfmon.c : uses XMACROS, which checkpatch doesn't understand.
+ # feature_id.c : uses XMACROS, which checkpatch doesn't understand.
+-CHECKPATCH_IGNORE := "src/arch/aarch64/hypervisor/debug_el1.c\|src/arch/aarch64/hypervisor/perfmon.c\|src/arch/aarch64/hypervisor/feature_id.c"
++# timer_el1.c : uses XMACROS, which checkpatch doesn't understand.
++CHECKPATCH_IGNORE := "src/arch/aarch64/hypervisor/debug_el1.c\|src/arch/aarch64/hypervisor/perfmon.c\|src/arch/aarch64/hypervisor/feature_id.c\|src/arch/aarch64/hypervisor/timer_el1.c"
+
+ OUT ?= out/$(PROJECT)
+ OUT_DIR = out/$(PROJECT)
+diff --git a/src/arch/aarch64/hypervisor/BUILD.gn b/src/arch/aarch64/hypervisor/BUILD.gn
+index 6068d1e..de1a414 100644
+--- a/src/arch/aarch64/hypervisor/BUILD.gn
++++ b/src/arch/aarch64/hypervisor/BUILD.gn
+@@ -45,6 +45,7 @@ source_set("hypervisor") {
+ "handler.c",
+ "perfmon.c",
+ "psci_handler.c",
++ "timer_el1.c",
+ "vm.c",
+ ]
+
+diff --git a/src/arch/aarch64/hypervisor/cpu.c b/src/arch/aarch64/hypervisor/cpu.c
+index c6cebdd..cb41e6e 100644
+--- a/src/arch/aarch64/hypervisor/cpu.c
++++ b/src/arch/aarch64/hypervisor/cpu.c
+@@ -91,13 +91,20 @@ void arch_regs_reset(struct vcpu *vcpu)
+ if (is_primary) {
+ /*
+ * cnthctl_el2 is redefined when VHE is enabled.
+- * EL1PCTEN, don't trap phys cnt access.
+- * EL1PCEN, don't trap phys timer access.
++ * EL1PCTEN, don't trap phys cnt access. Except when in
++ * secure world without vhe.
++ * EL1PCEN, don't trap phys timer access. Except when in
++ * secure world without vhe.
+ */
+ if (has_vhe_support()) {
+ cnthctl |= (1U << 10) | (1U << 11);
+ } else {
++#if SECURE_WORLD == 1
++ cnthctl &= ~(1U << 0);
++ cnthctl &= ~(1U << 1);
++#else
+ cnthctl |= (1U << 0) | (1U << 1);
++#endif
+ }
+ }
+
+diff --git a/src/arch/aarch64/hypervisor/handler.c b/src/arch/aarch64/hypervisor/handler.c
+index cd64d68..c9068c5 100644
+--- a/src/arch/aarch64/hypervisor/handler.c
++++ b/src/arch/aarch64/hypervisor/handler.c
+@@ -34,6 +34,7 @@
+ #include "psci_handler.h"
+ #include "smc.h"
+ #include "sysregs.h"
++#include "timer_el1.h"
+
+ /**
+ * Hypervisor Fault Address Register Non-Secure.
+@@ -1276,6 +1277,11 @@ void handle_system_register_access(uintreg_t esr_el2)
+ inject_el1_unknown_exception(vcpu, esr_el2);
+ return;
+ }
++ } else if (timer_el1_is_register_access(esr_el2)) {
++ if (!timer_el1_process_access(vcpu, vm_id, esr_el2)) {
++ inject_el1_unknown_exception(vcpu, esr_el2);
++ return;
++ }
+ } else {
+ inject_el1_unknown_exception(vcpu, esr_el2);
+ return;
+diff --git a/src/arch/aarch64/hypervisor/timer_el1.c b/src/arch/aarch64/hypervisor/timer_el1.c
+new file mode 100644
+index 0000000..c30e554
+--- /dev/null
++++ b/src/arch/aarch64/hypervisor/timer_el1.c
+@@ -0,0 +1,104 @@
++/*
++ * Copyright 2022 The Hafnium Authors.
++ *
++ * Use of this source code is governed by a BSD-style
++ * license that can be found in the LICENSE file or at
++ * https://opensource.org/licenses/BSD-3-Clause.
++ */
++
++#include "timer_el1.h"
++
++#include "hf/dlog.h"
++
++#include "msr.h"
++#include "sysregs.h"
++
++/*
++ * Physical timer (CNTP) register encodings as defined in
++ * table D13-8 of the ARMv8 ARM (DDI0487F).
++ * TYPE, op0, op1, crn, crm, op2
++ * The register names are the concatenation of
++ * "CNTP_", TYPE and "_EL2".
++ */
++#define CNTP_REGISTERS \
++ X(CTL, 3, 3, 14, 2, 1) \
++ X(CVAL, 3, 3, 14, 2, 2) \
++ X(TVAL, 3, 3, 14, 2, 0) \
++
++bool timer_el1_is_register_access(uintreg_t esr)
++{
++ uintreg_t sys_register = GET_ISS_SYSREG(esr);
++ bool is_timer_access;
++ switch (sys_register) {
++#define X(type, op0, op1, crn, crm, op2) \
++ case (GET_ISS_ENCODING(op0, op1, crn, crm, op2)): \
++ is_timer_access = true; \
++ break;
++ CNTP_REGISTERS
++#undef X
++ case (GET_ISS_ENCODING(3, 3, 14, 0, 1)):
++ is_timer_access = true;
++ break;
++ default:
++ is_timer_access = false;
++ }
++
++ return is_timer_access;
++}
++
++/* Accesses to CNTP timer emulated with CNTHPS */
++bool timer_el1_process_access(struct vcpu *vcpu, ffa_vm_id_t vm_id,
++ uintreg_t esr)
++{
++ uintreg_t sys_register = GET_ISS_SYSREG(esr);
++ uintreg_t rt_register = GET_ISS_RT(esr);
++ uintreg_t value;
++
++ if (ISS_IS_READ(esr)) {
++ switch (sys_register) {
++#define X(type, op0, op1, crn, crm, op2) \
++ case (GET_ISS_ENCODING(op0, op1, crn, crm, op2)): \
++ value = read_msr(MSR_CNTHPS_##type##_EL2); \
++ vcpu->regs.r[rt_register] = value; \
++ break;
++ CNTP_REGISTERS
++#undef X
++ case (GET_ISS_ENCODING(3, 3, 14, 0, 1)):
++ value = read_msr(cntpct_el0);
++ vcpu->regs.r[rt_register] = value;
++ break;
++ default:
++ dlog_notice(
++ "Unsupported timer register "
++ "read: "
++ "op0=%d, op1=%d, crn=%d, crm=%d, op2=%d, "
++ "rt=%d.\n",
++ GET_ISS_OP0(esr), GET_ISS_OP1(esr),
++ GET_ISS_CRN(esr), GET_ISS_CRM(esr),
++ GET_ISS_OP2(esr), GET_ISS_RT(esr));
++ break;
++ }
++ } else {
++ value = vcpu->regs.r[rt_register];
++ switch (sys_register) {
++#define X(type, op0, op1, crn, crm, op2) \
++ case (GET_ISS_ENCODING(op0, op1, crn, crm, op2)): \
++ write_msr(MSR_CNTHPS_##type##_EL2, value); \
++ break;
++ CNTP_REGISTERS
++#undef X
++ default:
++ dlog_notice(
++ "Unsupported timer register "
++ "write: "
++ "op0=%d, op1=%d, crn=%d, crm=%d, op2=%d, "
++ "rt=%d, value=%d.\n",
++ GET_ISS_OP0(esr), GET_ISS_OP1(esr),
++ GET_ISS_CRN(esr), GET_ISS_CRM(esr),
++ GET_ISS_OP2(esr), GET_ISS_RT(esr), value);
++ break;
++ }
++ }
++
++ return true;
++}
+diff --git a/src/arch/aarch64/hypervisor/timer_el1.h b/src/arch/aarch64/hypervisor/timer_el1.h
+new file mode 100644
+index 0000000..04a43b6
+--- /dev/null
++++ b/src/arch/aarch64/hypervisor/timer_el1.h
+@@ -0,0 +1,20 @@
++/*
++ * Copyright 2022 The Hafnium Authors.
++ *
++ * Use of this source code is governed by a BSD-style
++ * license that can be found in the LICENSE file or at
++ * https://opensource.org/licenses/BSD-3-Clause.
++ */
++
++#pragma once
++
++#include "hf/arch/types.h"
++
++#include "hf/cpu.h"
++
++#include "vmapi/hf/ffa.h"
++
++bool timer_el1_is_register_access(uintreg_t esr);
++
++bool timer_el1_process_access(struct vcpu *vcpu, ffa_vm_id_t vm_id,
++ uintreg_t esr);
+diff --git a/src/arch/aarch64/msr.h b/src/arch/aarch64/msr.h
+index cd6778b..55e7833 100644
+--- a/src/arch/aarch64/msr.h
++++ b/src/arch/aarch64/msr.h
+@@ -126,3 +126,11 @@
+ #define MSR_ELR_EL12 S3_5_C4_C0_1
+
+ #endif
++
++/*
++ * Secure EL2 Physical timer (CNTHPS) register encodings as defined in
++ * table D13-8 of the ARMv8 ARM (DDI0487F).
++ */
++#define MSR_CNTHPS_CTL_EL2 S3_4_C14_C5_1
++#define MSR_CNTHPS_CVAL_EL2 S3_4_C14_C5_2
++#define MSR_CNTHPS_TVAL_EL2 S3_4_C14_C5_0
+--
+2.17.1
+