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
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);
+ }
+
node = fdt_find_node("/timer");
fdt_node_set_property(node, "interrupts",
- interrupts, sizeof(interrupts));
+ interrupts, sz);
fdt_node_set_string_property(node, "status", "okay");
}
--
2.51.0
[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