From: Marc Zyngier 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 Date: Sun, 12 Apr 2026 17:54:59 +0100 On Sun, 12 Apr 2026 11:18:24 +0100, Marc Zyngier 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 > --- > 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.