Download raw body.
[PATCH 3/4] Pick the correct timer interrupt for the running EL
[PATCH 4/4] Generate FDT entry for the EL2 virtual timer when available in GTDT
[PATCH 4/4] Generate FDT entry for the EL2 virtual timer when available in GTDT
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.
[PATCH 3/4] Pick the correct timer interrupt for the running EL
[PATCH 4/4] Generate FDT entry for the EL2 virtual timer when available in GTDT
[PATCH 4/4] Generate FDT entry for the EL2 virtual timer when available in GTDT