Index | Thread | Search

From:
Marc Zyngier <maz@kernel.org>
Subject:
Re: [PATCH 4/4] Generate FDT entry for the EL2 virtual timer when available in GTDT
To:
tech@openbsd.org
Cc:
kettenis@openbsd.org, Vincent Legoll <legoll@online.fr>
Date:
Sun, 12 Apr 2026 17:54:59 +0100

Download raw body.

Thread
On Sun, 12 Apr 2026 11:18:24 +0100,
Marc Zyngier <maz@kernel.org> wrote:
> 
> The GTDT ACPI table optionally indicates the interrupt number for
> the EL2 virtual timer. Popagate this into the generated FDT so that
> it can be used when running at EL2.
> 
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
>  sys/arch/arm64/stand/efiboot/efiacpi.c | 15 +++++++++++++--
>  1 file changed, 13 insertions(+), 2 deletions(-)
> 
> diff --git a/sys/arch/arm64/stand/efiboot/efiacpi.c b/sys/arch/arm64/stand/efiboot/efiacpi.c
> index 6e0ace3ef..02fa4fe80 100644
> --- a/sys/arch/arm64/stand/efiboot/efiacpi.c
> +++ b/sys/arch/arm64/stand/efiboot/efiacpi.c
> @@ -228,6 +228,8 @@ struct acpi_gtdt {
>  	uint64_t	cnt_read_base;
>  	uint32_t	platform_timer_count;
>  	uint32_t	platform_timer_offset;
> +	uint32_t	virt_el2_interrupt;
> +	uint32_t	virt_el2_flags;
>  } __packed;
>  
>  struct acpi_madt {
> @@ -402,7 +404,8 @@ efi_acpi_gtdt(struct acpi_table_header *hdr)
>  	const uint32_t map[] = { 0x4, 0x1, 0x8, 0x2 };
>  	const uint32_t mask = ACPI_GTDT_TIMER_TRIGGER_EDGE |
>  	    ACPI_GTDT_TIMER_POLARITY_LOW;
> -	uint32_t interrupts[12];
> +	uint32_t interrupts[15];
> +	size_t sz = sizeof(interrupts);
>  	void *node;
>  
>  	/* All interrupts are supposed to be PPIs. */
> @@ -419,9 +422,17 @@ efi_acpi_gtdt(struct acpi_table_header *hdr)
>  	interrupts[10] = htobe32(gtdt->nonsec_el2_interrupt - 16);
>  	interrupts[11] = htobe32(map[gtdt->nonsec_el2_flags & mask]);
>  
> +	if (gtdt->hdr_length > 0x60) {
> +		interrupts[12] = htobe32(1);
> +		interrupts[13] = htobe32(gtdt->virt_el2_interrupt - 16);
> +		interrupts[14] = htobe32(map[gtdt->virt_el2_flags & mask]);
> +
> +		sz += 3 * sizeof(uint32_t);

As pointed out by Vincent off-list, the initialisation and this line
combine badly, resulting in an embarrassing bug.

The init part should reflect the later correction with something like
this:

diff --git stand/efiboot/efiacpi.c stand/efiboot/efiacpi.c
index 02fa4fe80..ca6defd7d 100644
--- stand/efiboot/efiacpi.c
+++ stand/efiboot/efiacpi.c
@@ -405,7 +405,7 @@ efi_acpi_gtdt(struct acpi_table_header *hdr)
 	const uint32_t mask = ACPI_GTDT_TIMER_TRIGGER_EDGE |
 	    ACPI_GTDT_TIMER_POLARITY_LOW;
 	uint32_t interrupts[15];
-	size_t sz = sizeof(interrupts);
+	size_t sz = sizeof(interrupts) - 3 * sizeof(uint32_t);
 	void *node;
 
 	/* All interrupts are supposed to be PPIs. */

Apologies for the noise.

	M.

-- 
Without deviation from the norm, progress is not possible.