kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Nikos Nikoleris <nikos.nikoleris@arm.com>
To: kvm@vger.kernel.org
Cc: andrew.jones@linux.dev, drjones@redhat.com, pbonzini@redhat.com,
	jade.alglave@arm.com, alexandru.elisei@arm.com,
	ricarkol@google.com
Subject: [kvm-unit-tests PATCH v3 09/27] arm/arm64: Add support for timer initialization through ACPI
Date: Thu, 30 Jun 2022 11:03:06 +0100	[thread overview]
Message-ID: <20220630100324.3153655-10-nikos.nikoleris@arm.com> (raw)
In-Reply-To: <20220630100324.3153655-1-nikos.nikoleris@arm.com>

For systems with ACPI support, we can discover timers through the ACPI
GTDT table. This change implements the code to discover timers through
the GTDT and adds ACPI support in timer_save_state. This change
retains the default behavior; we check if a valid DT is provided, if
not, we try to discover timers using ACPI.

Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
---
 arm/Makefile.common |  1 +
 lib/arm/asm/timer.h |  2 ++
 lib/acpi.h          | 18 +++++++++++
 lib/arm/setup.c     | 39 ----------------------
 lib/arm/timer.c     | 79 +++++++++++++++++++++++++++++++++++++++++++++
 arm/micro-bench.c   |  4 +--
 arm/timer.c         | 10 +++---
 7 files changed, 107 insertions(+), 46 deletions(-)
 create mode 100644 lib/arm/timer.c

diff --git a/arm/Makefile.common b/arm/Makefile.common
index 8e9b3bb..5be42c0 100644
--- a/arm/Makefile.common
+++ b/arm/Makefile.common
@@ -53,6 +53,7 @@ cflatobjs += lib/arm/psci.o
 cflatobjs += lib/arm/smp.o
 cflatobjs += lib/arm/delay.o
 cflatobjs += lib/arm/gic.o lib/arm/gic-v2.o lib/arm/gic-v3.o
+cflatobjs += lib/arm/timer.o
 
 OBJDIRS += lib/arm
 
diff --git a/lib/arm/asm/timer.h b/lib/arm/asm/timer.h
index f75cc67..aaf839f 100644
--- a/lib/arm/asm/timer.h
+++ b/lib/arm/asm/timer.h
@@ -27,5 +27,7 @@ extern struct timer_state __timer_state;
 #define TIMER_PTIMER_IRQ (__timer_state.ptimer.irq)
 #define TIMER_VTIMER_IRQ (__timer_state.vtimer.irq)
 
+void timer_save_state(void);
+
 #endif /* !__ASSEMBLY__ */
 #endif /* _ASMARM_TIMER_H_ */
diff --git a/lib/acpi.h b/lib/acpi.h
index 1cd99c5..9910c39 100644
--- a/lib/acpi.h
+++ b/lib/acpi.h
@@ -18,6 +18,7 @@
 #define FACP_SIGNATURE ACPI_SIGNATURE('F','A','C','P')
 #define FACS_SIGNATURE ACPI_SIGNATURE('F','A','C','S')
 #define SPCR_SIGNATURE ACPI_SIGNATURE('S','P','C','R')
+#define GTDT_SIGNATURE ACPI_SIGNATURE('G','T','D','T')
 
 
 #define ACPI_SIGNATURE_8BYTE(c1, c2, c3, c4, c5, c6, c7, c8)	\
@@ -173,6 +174,23 @@ struct spcr_descriptor {
 	u32 reserved2;
 };
 
+struct acpi_table_gtdt {
+	ACPI_TABLE_HEADER_DEF	/* ACPI common table header */
+	u64 counter_block_addresss;
+	u32 reserved;
+	u32 secure_el1_interrupt;
+	u32 secure_el1_flags;
+	u32 non_secure_el1_interrupt;
+	u32 non_secure_el1_flags;
+	u32 virtual_timer_interrupt;
+	u32 virtual_timer_flags;
+	u32 non_secure_el2_interrupt;
+	u32 non_secure_el2_flags;
+	u64 counter_read_block_address;
+	u32 platform_timer_count;
+	u32 platform_timer_offset;
+};
+
 #pragma pack(0)
 
 void set_efi_rsdp(struct rsdp_descriptor *rsdp);
diff --git a/lib/arm/setup.c b/lib/arm/setup.c
index bcdf0d7..1572c64 100644
--- a/lib/arm/setup.c
+++ b/lib/arm/setup.c
@@ -35,8 +35,6 @@
 
 extern unsigned long etext;
 
-struct timer_state __timer_state;
-
 char *initrd;
 u32 initrd_size;
 
@@ -199,43 +197,6 @@ static void mem_init(phys_addr_t freemem_start)
 	page_alloc_ops_enable();
 }
 
-static void timer_save_state(void)
-{
-	const struct fdt_property *prop;
-	const void *fdt = dt_fdt();
-	int node, len;
-	u32 *data;
-
-	node = fdt_node_offset_by_compatible(fdt, -1, "arm,armv8-timer");
-	assert(node >= 0 || node == -FDT_ERR_NOTFOUND);
-
-	if (node == -FDT_ERR_NOTFOUND) {
-		__timer_state.ptimer.irq = -1;
-		__timer_state.vtimer.irq = -1;
-		return;
-	}
-
-	/*
-	 * From Linux devicetree timer binding documentation
-	 *
-	 * interrupts <type irq flags>:
-	 *	secure timer irq
-	 *	non-secure timer irq		(ptimer)
-	 *	virtual timer irq		(vtimer)
-	 *	hypervisor timer irq
-	 */
-	prop = fdt_get_property(fdt, node, "interrupts", &len);
-	assert(prop && len == (4 * 3 * sizeof(u32)));
-
-	data = (u32 *)prop->data;
-	assert(fdt32_to_cpu(data[3]) == 1 /* PPI */);
-	__timer_state.ptimer.irq = fdt32_to_cpu(data[4]);
-	__timer_state.ptimer.irq_flags = fdt32_to_cpu(data[5]);
-	assert(fdt32_to_cpu(data[6]) == 1 /* PPI */);
-	__timer_state.vtimer.irq = fdt32_to_cpu(data[7]);
-	__timer_state.vtimer.irq_flags = fdt32_to_cpu(data[8]);
-}
-
 void setup(const void *fdt, phys_addr_t freemem_start)
 {
 	void *freemem;
diff --git a/lib/arm/timer.c b/lib/arm/timer.c
new file mode 100644
index 0000000..507d9c8
--- /dev/null
+++ b/lib/arm/timer.c
@@ -0,0 +1,79 @@
+/*
+ * Initialize timers.
+ *
+ * Copyright (C) 2022, Arm Ltd., Nikos Nikoleris <nikos.nikoleris@arm.com>
+ * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#include <libcflat.h>
+#include <acpi.h>
+#include <devicetree.h>
+#include <libfdt/libfdt.h>
+#include <asm/gic.h>
+#include <asm/timer.h>
+
+struct timer_state __timer_state;
+
+static void timer_save_state_fdt(void)
+{
+	const struct fdt_property *prop;
+	const void *fdt = dt_fdt();
+	int node, len;
+	u32 *data;
+
+	node = fdt_node_offset_by_compatible(fdt, -1, "arm,armv8-timer");
+	assert(node >= 0 || node == -FDT_ERR_NOTFOUND);
+
+	if (node == -FDT_ERR_NOTFOUND) {
+		__timer_state.ptimer.irq = -1;
+		__timer_state.vtimer.irq = -1;
+		return;
+	}
+
+	/*
+	 * From Linux devicetree timer binding documentation
+	 *
+	 * interrupts <type irq flags>:
+	 *	secure timer irq
+	 *	non-secure timer irq		(ptimer)
+	 *	virtual timer irq		(vtimer)
+	 *	hypervisor timer irq
+	 */
+	prop = fdt_get_property(fdt, node, "interrupts", &len);
+	assert(prop && len == (4 * 3 * sizeof(u32)));
+
+	data = (u32 *)prop->data;
+	assert(fdt32_to_cpu(data[3]) == 1 /* PPI */);
+	__timer_state.ptimer.irq = PPI(fdt32_to_cpu(data[4]));
+	__timer_state.ptimer.irq_flags = fdt32_to_cpu(data[5]);
+	assert(fdt32_to_cpu(data[6]) == 1 /* PPI */);
+	__timer_state.vtimer.irq = PPI(fdt32_to_cpu(data[7]));
+	__timer_state.vtimer.irq_flags = fdt32_to_cpu(data[8]);
+}
+
+static void timer_save_state_acpi(void)
+{
+	struct acpi_table_gtdt *gtdt = find_acpi_table_addr(GTDT_SIGNATURE);
+
+	if (!gtdt) {
+		printf("Cannot find ACPI GTDT");
+		__timer_state.ptimer.irq = -1;
+		__timer_state.vtimer.irq = -1;
+		return;
+	}
+
+	__timer_state.ptimer.irq = gtdt->non_secure_el1_interrupt;
+	__timer_state.ptimer.irq_flags = gtdt->non_secure_el1_flags;
+
+	__timer_state.vtimer.irq = gtdt->virtual_timer_interrupt;
+	__timer_state.vtimer.irq_flags = gtdt->virtual_timer_flags;
+}
+
+void timer_save_state(void)
+{
+	if (dt_available())
+		timer_save_state_fdt();
+	else
+		timer_save_state_acpi();
+}
diff --git a/arm/micro-bench.c b/arm/micro-bench.c
index 8436612..5be9b18 100644
--- a/arm/micro-bench.c
+++ b/arm/micro-bench.c
@@ -43,7 +43,7 @@ static void gic_irq_handler(struct pt_regs *regs)
 	irq_received = true;
 	gic_write_eoir(irqstat);
 
-	if (irqstat == PPI(TIMER_VTIMER_IRQ)) {
+	if (irqstat == TIMER_VTIMER_IRQ) {
 		write_sysreg((ARCH_TIMER_CTL_IMASK | ARCH_TIMER_CTL_ENABLE),
 			     cntv_ctl_el0);
 		isb();
@@ -229,7 +229,7 @@ static bool timer_prep(void)
 		assert_msg(0, "Unreachable");
 	}
 
-	writel(1 << PPI(TIMER_VTIMER_IRQ), gic_isenabler);
+	writel(1 << TIMER_VTIMER_IRQ, gic_isenabler);
 	write_sysreg(ARCH_TIMER_CTL_IMASK | ARCH_TIMER_CTL_ENABLE, cntv_ctl_el0);
 	isb();
 
diff --git a/arm/timer.c b/arm/timer.c
index c4e7b10..a4a8281 100644
--- a/arm/timer.c
+++ b/arm/timer.c
@@ -139,7 +139,7 @@ static struct timer_info ptimer_info = {
 
 static void set_timer_irq_enabled(struct timer_info *info, bool enabled)
 {
-	u32 val = 1 << PPI(info->irq);
+	u32 val = 1 << info->irq;
 
 	if (enabled)
 		writel(val, gic_isenabler);
@@ -153,9 +153,9 @@ static void irq_handler(struct pt_regs *regs)
 	u32 irqstat = gic_read_iar();
 	u32 irqnr = gic_iar_irqnr(irqstat);
 
-	if (irqnr == PPI(vtimer_info.irq)) {
+	if (irqnr == vtimer_info.irq) {
 		info = &vtimer_info;
-	} else if (irqnr == PPI(ptimer_info.irq)) {
+	} else if (irqnr == ptimer_info.irq) {
 		info = &ptimer_info;
 	} else {
 		if (irqnr != GICC_INT_SPURIOUS)
@@ -185,9 +185,9 @@ static bool gic_timer_check_state(struct timer_info *info,
 	/* Wait for up to 1s for the GIC to sample the interrupt. */
 	for (i = 0; i < 10; i++) {
 		mdelay(100);
-		if (gic_irq_state(PPI(info->irq)) == expected_state) {
+		if (gic_irq_state(info->irq) == expected_state) {
 			mdelay(100);
-			if (gic_irq_state(PPI(info->irq)) == expected_state)
+			if (gic_irq_state(info->irq) == expected_state)
 				return true;
 		}
 	}
-- 
2.25.1


  parent reply	other threads:[~2022-06-30 10:04 UTC|newest]

Thread overview: 72+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-30 10:02 [kvm-unit-tests PATCH v3 00/27] EFI and ACPI support for arm64 Nikos Nikoleris
2022-06-30 10:02 ` [kvm-unit-tests PATCH v3 01/27] lib: Fix style for acpi.{c,h} Nikos Nikoleris
2022-07-01  9:27   ` Andrew Jones
2022-07-01  9:52     ` Nikos Nikoleris
2022-07-01 10:12       ` Andrew Jones
2022-06-30 10:02 ` [kvm-unit-tests PATCH v3 02/27] x86: Avoid references to fields of ACPI tables Nikos Nikoleris
2022-06-30 10:03 ` [kvm-unit-tests PATCH v3 03/27] lib: Ensure all struct definition for ACPI tables are packed Nikos Nikoleris
2022-07-01  9:35   ` Andrew Jones
2022-06-30 10:03 ` [kvm-unit-tests PATCH v3 04/27] lib: Add support for the XSDT ACPI table Nikos Nikoleris
2022-07-01  9:49   ` Andrew Jones
2022-06-30 10:03 ` [kvm-unit-tests PATCH v3 05/27] lib: Extend the definition of the ACPI table FADT Nikos Nikoleris
2022-06-30 10:03 ` [kvm-unit-tests PATCH v3 06/27] devicetree: Check if fdt is NULL before returning that a DT is available Nikos Nikoleris
2022-07-01  9:55   ` Andrew Jones
2022-06-30 10:03 ` [kvm-unit-tests PATCH v3 07/27] arm/arm64: Add support for setting up the PSCI conduit through ACPI Nikos Nikoleris
2022-06-30 10:03 ` [kvm-unit-tests PATCH v3 08/27] arm/arm64: Add support for discovering the UART " Nikos Nikoleris
2022-06-30 10:03 ` Nikos Nikoleris [this message]
2022-06-30 10:03 ` [kvm-unit-tests PATCH v3 10/27] arm/arm64: Add support for cpu initialization " Nikos Nikoleris
2022-06-30 10:03 ` [kvm-unit-tests PATCH v3 11/27] arm/arm64: Add support for gic " Nikos Nikoleris
2022-06-30 10:03 ` [kvm-unit-tests PATCH v3 12/27] lib/printf: Support for precision modifier in printf Nikos Nikoleris
2022-06-30 10:03 ` [kvm-unit-tests PATCH v3 13/27] lib/printf: Add support for printing wide strings Nikos Nikoleris
2022-06-30 10:03 ` [kvm-unit-tests PATCH v3 14/27] lib/efi: Add support for getting the cmdline Nikos Nikoleris
2022-06-30 10:03 ` [kvm-unit-tests PATCH v3 15/27] arm/arm64: mmu_disable: Clean and invalidate before disabling Nikos Nikoleris
2022-06-30 10:20   ` Alexandru Elisei
2022-06-30 11:08     ` Nikos Nikoleris
2022-06-30 11:24       ` Alexandru Elisei
2022-06-30 15:16         ` Nikos Nikoleris
2022-06-30 15:57           ` Alexandru Elisei
2022-07-01  9:12             ` Andrew Jones
2022-07-01 10:24               ` Alexandru Elisei
2022-07-01 11:16                 ` Andrew Jones
2022-07-11 14:23                   ` Alexandru Elisei
2022-07-01 11:34                 ` Nikos Nikoleris
2022-07-01 14:39                   ` Alexandru Elisei
2022-07-01 10:36           ` Andrew Jones
2022-06-30 10:03 ` [kvm-unit-tests PATCH v3 16/27] arm/arm64: Rename etext to _etext Nikos Nikoleris
2022-06-30 10:03 ` [kvm-unit-tests PATCH v3 17/27] lib: Avoid ms_abi for calls related to EFI on arm64 Nikos Nikoleris
2022-06-30 10:03 ` [kvm-unit-tests PATCH v3 18/27] arm64: Add a new type of memory type flag MR_F_RESERVED Nikos Nikoleris
2022-06-30 10:03 ` [kvm-unit-tests PATCH v3 19/27] arm/arm64: Add a setup sequence for systems that boot through EFI Nikos Nikoleris
2022-06-30 10:54   ` Alexandru Elisei
2022-07-19 14:08   ` Alexandru Elisei
2022-08-12 14:34     ` Nikos Nikoleris
2022-06-30 10:03 ` [kvm-unit-tests PATCH v3 20/27] arm64: Copy code from GNU-EFI Nikos Nikoleris
2022-06-30 10:03 ` [kvm-unit-tests PATCH v3 21/27] arm64: Change GNU-EFI imported file to use defined types Nikos Nikoleris
2022-06-30 10:03 ` [kvm-unit-tests PATCH v3 22/27] arm64: Use code from the gnu-efi when booting with EFI Nikos Nikoleris
2022-07-01  0:43   ` Ricardo Koller
2022-07-04  9:18     ` Nikos Nikoleris
2022-06-30 10:03 ` [kvm-unit-tests PATCH v3 23/27] lib: Avoid external dependency in libelf Nikos Nikoleris
2022-06-30 10:03 ` [kvm-unit-tests PATCH v3 24/27] x86: Move x86_64-specific EFI CFLAGS to x86_64 Makefile Nikos Nikoleris
2022-06-30 10:03 ` [kvm-unit-tests PATCH v3 25/27] arm64: Add support for efi in Makefile Nikos Nikoleris
2022-07-12 13:39   ` Alexandru Elisei
2022-07-12 20:50     ` Nikos Nikoleris
2022-07-13  8:46       ` Alexandru Elisei
2022-07-13  9:17         ` Nikos Nikoleris
2022-07-15 13:59           ` Nikos Nikoleris
2022-06-30 10:03 ` [kvm-unit-tests PATCH v3 26/27] lib: arm: Print test exit status Nikos Nikoleris
2022-07-01 10:48   ` Andrew Jones
2022-06-30 10:03 ` [kvm-unit-tests PATCH v3 27/27] arm64: Add an efi/run script Nikos Nikoleris
2022-07-19 15:28 ` [kvm-unit-tests PATCH v3 00/27] EFI and ACPI support for arm64 Alexandru Elisei
2022-07-22 10:57   ` Nikos Nikoleris
2022-07-22 14:41     ` Alexandru Elisei
2022-08-01 18:23       ` Nikos Nikoleris
2022-08-02 10:19         ` Alexandru Elisei
2022-08-02 10:46           ` Andrew Jones
2022-08-03 12:51             ` Nikos Nikoleris
2022-08-09 11:16 ` Alexandru Elisei
2022-08-09 15:29   ` Sean Christopherson
2022-08-10  9:17     ` Alexandru Elisei
2022-08-10 14:58       ` Sean Christopherson
2022-08-10 15:04         ` Alexandru Elisei
2022-08-09 16:09   ` Nikos Nikoleris
2022-08-12 14:55     ` Alexandru Elisei
2022-08-12 15:49       ` Nikos Nikoleris

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220630100324.3153655-10-nikos.nikoleris@arm.com \
    --to=nikos.nikoleris@arm.com \
    --cc=alexandru.elisei@arm.com \
    --cc=andrew.jones@linux.dev \
    --cc=drjones@redhat.com \
    --cc=jade.alglave@arm.com \
    --cc=kvm@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=ricarkol@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).