feat(arch timer): introduce host timer driver
This patch introduces the host timer driver.
In subsequent patches, we will leverage host (EL2/S-EL2 physical) timer
module to enable support to program the deadline of SPs.
Change-Id: I32bc1eb37d993eaf1b0dd469df21862096d47429
Signed-off-by: Madhukar Pappireddy <madhukar.pappireddy@arm.com>
diff --git a/src/arch/aarch64/hypervisor/BUILD.gn b/src/arch/aarch64/hypervisor/BUILD.gn
index 2da7c0a..1d1582f 100644
--- a/src/arch/aarch64/hypervisor/BUILD.gn
+++ b/src/arch/aarch64/hypervisor/BUILD.gn
@@ -39,6 +39,7 @@
"ffa.c",
"fpu.c",
"handler.c",
+ "host_timer.c",
"perfmon.c",
"psci_handler.c",
"sme.c",
diff --git a/src/arch/aarch64/hypervisor/host_timer.c b/src/arch/aarch64/hypervisor/host_timer.c
new file mode 100644
index 0000000..c7273c8
--- /dev/null
+++ b/src/arch/aarch64/hypervisor/host_timer.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2024 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 "hf/arch/host_timer.h"
+
+#include "hf/arch/gicv3.h"
+
+#include "hf/plat/interrupts.h"
+
+#include "msr.h"
+#include "sysregs.h"
+
+/**
+ * Disable EL2/S-EL2 physical timer.
+ */
+void host_timer_disable(void)
+{
+#if SECURE_WORLD == 1
+ write_msr(cnthps_ctl_el2, 0);
+#else
+ write_msr(cnthp_ctl_el2, 0);
+#endif
+ /* Ensure that the write to ctl register has taken effect. */
+ isb();
+}
+
+/**
+ * Disable host timer and configure the PPI associated with it.
+ */
+void host_timer_init(void)
+{
+ host_timer_disable();
+
+#if SECURE_WORLD == 1
+ struct interrupt_descriptor int_desc = {
+ .interrupt_id = ARM_SEL2_TIMER_PHYS_INT,
+ .type = INT_DESC_TYPE_PPI,
+ .config = 1U, /* Level-sensitive */
+ .sec_state = INT_DESC_SEC_STATE_S,
+ .priority = 0x0,
+ .valid = true,
+ .mpidr_valid = false,
+ .enabled = true,
+ };
+
+ plat_interrupts_configure_interrupt(int_desc);
+#endif
+}
diff --git a/src/arch/aarch64/inc/hf/arch/gicv3.h b/src/arch/aarch64/inc/hf/arch/gicv3.h
index 055905d..c0f7e19 100644
--- a/src/arch/aarch64/inc/hf/arch/gicv3.h
+++ b/src/arch/aarch64/inc/hf/arch/gicv3.h
@@ -306,6 +306,11 @@
#endif /* GIC_EXT_INTID */
+/** PPIs associated with various peripheral timers. */
+#define ARM_SEL2_TIMER_PHYS_INT UINT32_C(20)
+#define ARM_EL1_VIRT_TIMER_PHYS_INT UINT32_C(27)
+#define ARM_EL1_PHYS_TIMER_PHYS_INT UINT32_C(30)
+
static inline uint32_t get_highest_pending_g0_interrupt_id(void)
{
return (uint32_t)read_msr(ICC_HPPIR0_EL1) & HPPIR0_EL1_INTID_MASK;