From: Mark Kettenis Subject: Re: [PATCH 4/4] Generate FDT entry for the EL2 virtual timer when available in GTDT To: Marc Zyngier Cc: tech@openbsd.org, kettenis@openbsd.org, legoll@online.fr Date: Sat, 25 Apr 2026 22:36:52 +0200 > Date: Sun, 12 Apr 2026 17:54:59 +0100 > From: Marc Zyngier Hi Marc, > 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. Thanks! The fields in the GTSD table are new in version 3 of the table. And the EL2 virtual timer interrupt field can be 0, which indicates no support. So I tightened up the check a bit. I also decided to add an "interrupt-names" property to make it easier to see what timer interrupts are supported. Anyone reviewing this should ignore the dt_blob.S bit; that is just the result of regenerating the blob from acpi.dts. ok? Index: arch/arm64/stand/efiboot/acpi.dts =================================================================== RCS file: /cvs/src/sys/arch/arm64/stand/efiboot/acpi.dts,v diff -u -p -r1.1 acpi.dts --- arch/arm64/stand/efiboot/acpi.dts 25 Jun 2018 22:39:14 -0000 1.1 +++ arch/arm64/stand/efiboot/acpi.dts 25 Apr 2026 20:27:47 -0000 @@ -29,6 +29,7 @@ timer { compatible = "arm,armv8-timer"; interrupts = <0 0 0>, <0 0 0>, <0 0 0>, <0 0 0>; + interrupt-names = "sec-phys", "phys", "virt", "hyp-phys"; status = "disabled"; }; Index: arch/arm64/stand/efiboot/conf.c =================================================================== RCS file: /cvs/src/sys/arch/arm64/stand/efiboot/conf.c,v diff -u -p -r1.53 conf.c --- arch/arm64/stand/efiboot/conf.c 25 Jan 2026 18:19:13 -0000 1.53 +++ arch/arm64/stand/efiboot/conf.c 25 Apr 2026 20:27:47 -0000 @@ -47,7 +47,7 @@ #include "efipxe.h" #include "softraid_arm64.h" -const char version[] = "1.24"; +const char version[] = "1.25"; int debug = 0; struct fs_ops file_system[] = { Index: arch/arm64/stand/efiboot/dt_blob.S =================================================================== RCS file: /cvs/src/sys/arch/arm64/stand/efiboot/dt_blob.S,v diff -u -p -r1.2 dt_blob.S --- arch/arm64/stand/efiboot/dt_blob.S 14 Mar 2022 19:09:32 -0000 1.2 +++ arch/arm64/stand/efiboot/dt_blob.S 25 Apr 2026 20:27:47 -0000 @@ -7,7 +7,10 @@ _dt_blob_start: dt_header: _dt_header: /* magic */ - .byte 0xd0; .byte 0x0d; .byte 0xfe; .byte 0xed + .byte 0xd0 + .byte 0x0d + .byte 0xfe + .byte 0xed /* totalsize */ .byte ((_dt_blob_abs_end - _dt_blob_start) >> 24) & 0xff .byte ((_dt_blob_abs_end - _dt_blob_start) >> 16) & 0xff @@ -29,11 +32,20 @@ _dt_header: .byte ((_dt_reserve_map - _dt_blob_start) >> 8) & 0xff .byte (_dt_reserve_map - _dt_blob_start) & 0xff /* version */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x11 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x11 /* last_comp_version */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x10 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x10 /* boot_cpuid_phys */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 /* size_dt_strings */ .byte ((_dt_strings_end - _dt_strings_start) >> 24) & 0xff .byte ((_dt_strings_end - _dt_strings_start) >> 16) & 0xff @@ -55,320 +67,900 @@ _dt_reserve_map: dt_struct_start: _dt_struct_start: /* FDT_BEGIN_NODE */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x01 - .string "" - .balign 4, 0 - /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x05 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .byte 0x41; .byte 0x43; .byte 0x50; .byte 0x49 - .byte 0x0 - .balign 4, 0 - /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x0d - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x06 - .byte 0x6f; .byte 0x70; .byte 0x65; .byte 0x6e - .byte 0x62; .byte 0x73; .byte 0x64; .byte 0x2c - .byte 0x61; .byte 0x63; .byte 0x70; .byte 0x69 - .byte 0x0 - .balign 4, 0 - /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x04 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x11 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x01 - .balign 4, 0 - /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x04 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x22 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02 - .balign 4, 0 - /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x04 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x31 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x01 + .asciz "" + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x05 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x41 + .byte 0x43 + .byte 0x50 + .byte 0x49 + .byte 0x0 + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x0d + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x06 + .byte 0x6f + .byte 0x70 + .byte 0x65 + .byte 0x6e + .byte 0x62 + .byte 0x73 + .byte 0x64 + .byte 0x2c + .byte 0x61 + .byte 0x63 + .byte 0x70 + .byte 0x69 + .byte 0x0 + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x04 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x11 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x01 + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x04 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x22 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x02 + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x04 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x31 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x02 .balign 4, 0 /* FDT_BEGIN_NODE */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x01 - .string "chosen" - .balign 4, 0 - /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x11 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x3d - .byte 0x73; .byte 0x65; .byte 0x72; .byte 0x69 - .byte 0x61; .byte 0x6c; .byte 0x30; .byte 0x3a - .byte 0x31; .byte 0x31; .byte 0x35; .byte 0x32 - .byte 0x30; .byte 0x30; .byte 0x6e; .byte 0x38 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x01 + .asciz "chosen" + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x11 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x3d + .byte 0x73 + .byte 0x65 + .byte 0x72 + .byte 0x69 + .byte 0x61 + .byte 0x6c + .byte 0x30 + .byte 0x3a + .byte 0x31 + .byte 0x31 + .byte 0x35 + .byte 0x32 + .byte 0x30 + .byte 0x30 + .byte 0x6e + .byte 0x38 .byte 0x0 .balign 4, 0 /* FDT_END_NODE */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x02 /* FDT_BEGIN_NODE */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x01 - .string "aliases" - .balign 4, 0 - /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x0a - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x49 - .byte 0x2f; .byte 0x73; .byte 0x65; .byte 0x72 - .byte 0x69; .byte 0x61; .byte 0x6c; .byte 0x40 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x01 + .asciz "aliases" + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x0a + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x49 + .byte 0x2f + .byte 0x73 + .byte 0x65 + .byte 0x72 + .byte 0x69 + .byte 0x61 + .byte 0x6c + .byte 0x40 .byte 0x30 .byte 0x0 .balign 4, 0 /* FDT_END_NODE */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x02 /* FDT_BEGIN_NODE */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x01 - .string "cpus" - .balign 4, 0 - /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x04 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x22 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02 - .balign 4, 0 - /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x04 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x31 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x01 + .asciz "cpus" + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x04 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x22 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x02 + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x04 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x31 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 .balign 4, 0 /* FDT_END_NODE */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x02 /* FDT_BEGIN_NODE */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x01 - .string "psci" - .balign 4, 0 - /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x0d - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x06 - .byte 0x61; .byte 0x72; .byte 0x6d; .byte 0x2c - .byte 0x70; .byte 0x73; .byte 0x63; .byte 0x69 - .byte 0x2d; .byte 0x31; .byte 0x2e; .byte 0x30 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x01 + .asciz "psci" + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x0d + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x06 + .byte 0x61 + .byte 0x72 + .byte 0x6d + .byte 0x2c + .byte 0x70 + .byte 0x73 + .byte 0x63 + .byte 0x69 + .byte 0x2d + .byte 0x31 + .byte 0x2e + .byte 0x30 .byte 0x0 .balign 4, 0 /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x04 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x51 - .byte 0x73; .byte 0x6d; .byte 0x63; .byte 0x00 - .balign 4, 0 - /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x09 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x58 - .byte 0x64; .byte 0x69; .byte 0x73; .byte 0x61 - .byte 0x62; .byte 0x6c; .byte 0x65; .byte 0x64 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x04 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x51 + .byte 0x73 + .byte 0x6d + .byte 0x63 + .byte 0x00 + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x09 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x58 + .byte 0x64 + .byte 0x69 + .byte 0x73 + .byte 0x61 + .byte 0x62 + .byte 0x6c + .byte 0x65 + .byte 0x64 .byte 0x0 .balign 4, 0 /* FDT_END_NODE */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x02 /* FDT_BEGIN_NODE */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x01 - .string "timer" - .balign 4, 0 - /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x10 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x06 - .byte 0x61; .byte 0x72; .byte 0x6d; .byte 0x2c - .byte 0x61; .byte 0x72; .byte 0x6d; .byte 0x76 - .byte 0x38; .byte 0x2d; .byte 0x74; .byte 0x69 - .byte 0x6d; .byte 0x65; .byte 0x72; .byte 0x00 - .balign 4, 0 - /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x30 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x5f - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .balign 4, 0 - /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x09 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x58 - .byte 0x64; .byte 0x69; .byte 0x73; .byte 0x61 - .byte 0x62; .byte 0x6c; .byte 0x65; .byte 0x64 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x01 + .asciz "timer" + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x10 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x06 + .byte 0x61 + .byte 0x72 + .byte 0x6d + .byte 0x2c + .byte 0x61 + .byte 0x72 + .byte 0x6d + .byte 0x76 + .byte 0x38 + .byte 0x2d + .byte 0x74 + .byte 0x69 + .byte 0x6d + .byte 0x65 + .byte 0x72 + .byte 0x00 + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x30 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x5f + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x1c + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x6a + .byte 0x73 + .byte 0x65 + .byte 0x63 + .byte 0x2d + .byte 0x70 + .byte 0x68 + .byte 0x79 + .byte 0x73 + .byte 0x00 + .byte 0x70 + .byte 0x68 + .byte 0x79 + .byte 0x73 + .byte 0x00 + .byte 0x76 + .byte 0x69 + .byte 0x72 + .byte 0x74 + .byte 0x00 + .byte 0x68 + .byte 0x79 + .byte 0x70 + .byte 0x2d + .byte 0x70 + .byte 0x68 + .byte 0x79 + .byte 0x73 + .byte 0x00 + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x09 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x58 + .byte 0x64 + .byte 0x69 + .byte 0x73 + .byte 0x61 + .byte 0x62 + .byte 0x6c + .byte 0x65 + .byte 0x64 .byte 0x0 .balign 4, 0 /* FDT_END_NODE */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x02 .globl gic gic: /* FDT_BEGIN_NODE */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x01 - .string "interrupt-controller@0" - .balign 4, 0 - /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x0c - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x06 - .byte 0x6f; .byte 0x70; .byte 0x65; .byte 0x6e - .byte 0x62; .byte 0x73; .byte 0x64; .byte 0x2c - .byte 0x67; .byte 0x69; .byte 0x63; .byte 0x00 - .balign 4, 0 - /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x04 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x6a - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .balign 4, 0 - /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x04 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x22 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02 - .balign 4, 0 - /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x04 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x31 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02 - .balign 4, 0 - /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x7b - .balign 4, 0 - /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x90 - .balign 4, 0 - /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x20 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x97 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .balign 4, 0 - /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x09 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x58 - .byte 0x64; .byte 0x69; .byte 0x73; .byte 0x61 - .byte 0x62; .byte 0x6c; .byte 0x65; .byte 0x64 - .byte 0x0 - .balign 4, 0 - /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x04 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x9b - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x01 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x01 + .asciz "interrupt-controller@0" + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x0c + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x06 + .byte 0x6f + .byte 0x70 + .byte 0x65 + .byte 0x6e + .byte 0x62 + .byte 0x73 + .byte 0x64 + .byte 0x2c + .byte 0x67 + .byte 0x69 + .byte 0x63 + .byte 0x00 + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x04 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x7a + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x04 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x22 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x02 + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x04 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x31 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x02 + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x8b + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0xa0 + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x20 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0xa7 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x09 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x58 + .byte 0x64 + .byte 0x69 + .byte 0x73 + .byte 0x61 + .byte 0x62 + .byte 0x6c + .byte 0x65 + .byte 0x64 + .byte 0x0 + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x04 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0xab + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x01 .balign 4, 0 /* FDT_END_NODE */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x02 .globl gic_end gic_end: .globl uart0 uart0: /* FDT_BEGIN_NODE */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x01 - .string "serial@0" - .balign 4, 0 - /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x0d - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x06 - .byte 0x6f; .byte 0x70; .byte 0x65; .byte 0x6e - .byte 0x62; .byte 0x73; .byte 0x64; .byte 0x2c - .byte 0x75; .byte 0x61; .byte 0x72; .byte 0x74 - .byte 0x0 - .balign 4, 0 - /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x10 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x97 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .balign 4, 0 - /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x09 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x58 - .byte 0x64; .byte 0x69; .byte 0x73; .byte 0x61 - .byte 0x62; .byte 0x6c; .byte 0x65; .byte 0x64 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x01 + .asciz "serial@0" + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x0d + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x06 + .byte 0x6f + .byte 0x70 + .byte 0x65 + .byte 0x6e + .byte 0x62 + .byte 0x73 + .byte 0x64 + .byte 0x2c + .byte 0x75 + .byte 0x61 + .byte 0x72 + .byte 0x74 + .byte 0x0 + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x10 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0xa7 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x09 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x58 + .byte 0x64 + .byte 0x69 + .byte 0x73 + .byte 0x61 + .byte 0x62 + .byte 0x6c + .byte 0x65 + .byte 0x64 .byte 0x0 .balign 4, 0 /* FDT_END_NODE */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x02 .globl uart0_end uart0_end: /* FDT_BEGIN_NODE */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x01 - .string "acpi@0" - .balign 4, 0 - /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x11 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x06 - .byte 0x6f; .byte 0x70; .byte 0x65; .byte 0x6e - .byte 0x62; .byte 0x73; .byte 0x64; .byte 0x2c - .byte 0x61; .byte 0x63; .byte 0x70; .byte 0x69 - .byte 0x2d; .byte 0x35; .byte 0x2e; .byte 0x30 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x01 + .asciz "acpi@0" + .balign 4, 0 + /* FDT_PROP */ + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x11 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x06 + .byte 0x6f + .byte 0x70 + .byte 0x65 + .byte 0x6e + .byte 0x62 + .byte 0x73 + .byte 0x64 + .byte 0x2c + .byte 0x61 + .byte 0x63 + .byte 0x70 + .byte 0x69 + .byte 0x2d + .byte 0x35 + .byte 0x2e + .byte 0x30 .byte 0x0 .balign 4, 0 /* FDT_PROP */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x03 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x10 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x97 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x03 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x10 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0xa7 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x00 .balign 4, 0 /* FDT_END_NODE */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x02 /* FDT_END_NODE */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x02 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x02 /* FDT_END */ - .byte 0x00; .byte 0x00; .byte 0x00; .byte 0x09 + .byte 0x00 + .byte 0x00 + .byte 0x00 + .byte 0x09 .globl dt_struct_end dt_struct_end: _dt_struct_end: .globl dt_strings_start dt_strings_start: _dt_strings_start: - .string "model" - .string "compatible" - .string "interrupt-parent" - .string "#address-cells" - .string "#size-cells" - .string "stdout-path" - .string "serial0" - .string "method" - .string "status" - .string "interrupts" - .string "#interrupt-cells" - .string "interrupt-controller" - .string "ranges" - .string "reg" - .string "phandle" + .asciz "model" + .asciz "compatible" + .asciz "interrupt-parent" + .asciz "#address-cells" + .asciz "#size-cells" + .asciz "stdout-path" + .asciz "serial0" + .asciz "method" + .asciz "status" + .asciz "interrupts" + .asciz "interrupt-names" + .asciz "#interrupt-cells" + .asciz "interrupt-controller" + .asciz "ranges" + .asciz "reg" + .asciz "phandle" .globl dt_strings_end dt_strings_end: _dt_strings_end: Index: arch/arm64/stand/efiboot/efiacpi.c =================================================================== RCS file: /cvs/src/sys/arch/arm64/stand/efiboot/efiacpi.c,v diff -u -p -r1.19 efiacpi.c --- arch/arm64/stand/efiboot/efiacpi.c 10 Feb 2025 20:40:26 -0000 1.19 +++ arch/arm64/stand/efiboot/efiacpi.c 25 Apr 2026 20:27:47 -0000 @@ -221,13 +221,15 @@ struct acpi_gtdt { #define ACPI_GTDT_TIMER_ALWAYS_ON 0x4 uint32_t nonsec_el1_interrupt; uint32_t nonsec_el1_flags; - uint32_t virt_interrupt; - uint32_t virt_flags; + uint32_t virt_el1_interrupt; + uint32_t virt_el1_flags; uint32_t nonsec_el2_interrupt; uint32_t nonsec_el2_flags; 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,8 +404,12 @@ efi_acpi_gtdt(struct acpi_table_header * 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]; + char interrupt_names[] = "sec-phys\0phys\0virt\0hyp-phys\0hyp-virt"; + uint32_t interrupts[15]; void *node; + size_t len; + + node = fdt_find_node("/timer"); /* All interrupts are supposed to be PPIs. */ interrupts[0] = htobe32(1); @@ -413,15 +419,25 @@ efi_acpi_gtdt(struct acpi_table_header * interrupts[4] = htobe32(gtdt->nonsec_el1_interrupt - 16); interrupts[5] = htobe32(map[gtdt->nonsec_el1_flags & mask]); interrupts[6] = htobe32(1); - interrupts[7] = htobe32(gtdt->virt_interrupt - 16); - interrupts[8] = htobe32(map[gtdt->virt_flags & mask]); + interrupts[7] = htobe32(gtdt->virt_el1_interrupt - 16); + interrupts[8] = htobe32(map[gtdt->virt_el1_flags & mask]); interrupts[9] = htobe32(1); interrupts[10] = htobe32(gtdt->nonsec_el2_interrupt - 16); interrupts[11] = htobe32(map[gtdt->nonsec_el2_flags & mask]); + len = 12 * sizeof(uint32_t); - node = fdt_find_node("/timer"); - fdt_node_set_property(node, "interrupts", - interrupts, sizeof(interrupts)); + if (gtdt->hdr.revision > 2 && gtdt->hdr.length >= 104 && + gtdt->virt_el2_interrupt > 0) { + interrupts[12] = htobe32(1); + interrupts[13] = htobe32(gtdt->virt_el2_interrupt - 16); + interrupts[14] = htobe32(map[gtdt->virt_el2_flags & mask]); + len = 15 * sizeof(uint32_t); + + fdt_node_set_property(node, "interrupt-names", + interrupt_names, sizeof(interrupt_names)); + } + + fdt_node_set_property(node, "interrupts", interrupts, len); fdt_node_set_string_property(node, "status", "okay"); }