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;