From: Nikos Nikoleris <nikos.nikoleris@arm.com>
To: kvm@vger.kernel.org, kvmarm@lists.linux.dev, andrew.jones@linux.dev
Cc: pbonzini@redhat.com, alexandru.elisei@arm.com, ricarkol@google.com
Subject: [PATCH v4 16/30] arm64: Add support for gic initialization through ACPI
Date: Mon, 13 Feb 2023 10:17:45 +0000 [thread overview]
Message-ID: <20230213101759.2577077-17-nikos.nikoleris@arm.com> (raw)
In-Reply-To: <20230213101759.2577077-1-nikos.nikoleris@arm.com>
In systems with ACPI support and when a DT is not provided, we can use
the MADTs to figure out if it implements a GICv2 or a GICv3 and
discover the GIC parameters. This change implements this but retains
the default behavior; we check if a valid DT is provided, if not, we
try to discover the cores in the system using ACPI.
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
---
lib/acpi.c | 9 +++-
lib/acpi.h | 46 +++++++++++++++-
lib/arm/gic.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++++-
lib/libcflat.h | 1 +
4 files changed, 191 insertions(+), 4 deletions(-)
diff --git a/lib/acpi.c b/lib/acpi.c
index bbe33d08..760cd8b2 100644
--- a/lib/acpi.c
+++ b/lib/acpi.c
@@ -103,11 +103,12 @@ void *find_acpi_table_addr(u32 sig)
return NULL;
}
-void acpi_table_parse_madt(enum acpi_madt_type mtype, acpi_table_handler handler)
+int acpi_table_parse_madt(enum acpi_madt_type mtype, acpi_table_handler handler)
{
struct acpi_table_madt *madt;
struct acpi_subtable_header *header;
void *end;
+ int count = 0;
madt = find_acpi_table_addr(MADT_SIGNATURE);
assert(madt);
@@ -116,9 +117,13 @@ void acpi_table_parse_madt(enum acpi_madt_type mtype, acpi_table_handler handler
end = (void *)((ulong) madt + madt->length);
while ((void *)header < end) {
- if (header->type == mtype)
+ if (header->type == mtype) {
handler(header);
+ count++;
+ }
header = (void *)(ulong) header + header->length;
}
+
+ return count;
}
diff --git a/lib/acpi.h b/lib/acpi.h
index af02fd83..a2c0f982 100644
--- a/lib/acpi.h
+++ b/lib/acpi.h
@@ -184,6 +184,50 @@ struct acpi_madt_generic_interrupt {
u16 spe_interrupt; /* ACPI 6.3 */
};
+#define ACPI_MADT_ENABLED (1) /* 00: Processor is usable if set */
+
+/* 12: Generic Distributor (ACPI 5.0 + ACPI 6.0 changes) */
+
+struct acpi_madt_generic_distributor {
+ struct acpi_subtable_header header;
+ u16 reserved; /* reserved - must be zero */
+ u32 gic_id;
+ u64 base_address;
+ u32 global_irq_base;
+ u8 version;
+ u8 reserved2[3]; /* reserved - must be zero */
+};
+
+/* Values for Version field above */
+
+enum acpi_madt_gic_version {
+ ACPI_MADT_GIC_VERSION_NONE = 0,
+ ACPI_MADT_GIC_VERSION_V1 = 1,
+ ACPI_MADT_GIC_VERSION_V2 = 2,
+ ACPI_MADT_GIC_VERSION_V3 = 3,
+ ACPI_MADT_GIC_VERSION_V4 = 4,
+ ACPI_MADT_GIC_VERSION_RESERVED = 5 /* 5 and greater are reserved */
+};
+
+/* 14: Generic Redistributor (ACPI 5.1) */
+
+struct acpi_madt_generic_redistributor {
+ struct acpi_subtable_header header;
+ u16 reserved; /* reserved - must be zero */
+ u64 base_address;
+ u32 length;
+};
+
+/* 15: Generic Translator (ACPI 6.0) */
+
+struct acpi_madt_generic_translator {
+ struct acpi_subtable_header header;
+ u16 reserved; /* reserved - must be zero */
+ u32 translation_id;
+ u64 base_address;
+ u32 reserved2;
+};
+
/* Values for MADT subtable type in struct acpi_subtable_header */
enum acpi_madt_type {
@@ -254,6 +298,6 @@ struct acpi_table_gtdt {
void set_efi_rsdp(struct acpi_table_rsdp *rsdp);
void *find_acpi_table_addr(u32 sig);
-void acpi_table_parse_madt(enum acpi_madt_type mtype, acpi_table_handler handler);
+int acpi_table_parse_madt(enum acpi_madt_type mtype, acpi_table_handler handler);
#endif
diff --git a/lib/arm/gic.c b/lib/arm/gic.c
index 1bfcfcfb..8fc5596f 100644
--- a/lib/arm/gic.c
+++ b/lib/arm/gic.c
@@ -3,6 +3,7 @@
*
* This work is licensed under the terms of the GNU LGPL, version 2.
*/
+#include <acpi.h>
#include <devicetree.h>
#include <asm/gic.h>
#include <asm/io.h>
@@ -120,7 +121,7 @@ int gic_version(void)
return 0;
}
-int gic_init(void)
+static int gic_init_fdt(void)
{
if (gicv2_init()) {
gic_common_ops = &gicv2_common_ops;
@@ -133,6 +134,142 @@ int gic_init(void)
return gic_version();
}
+#ifdef CONFIG_EFI
+
+#define ACPI_GICV2_DIST_MEM_SIZE (SZ_4K)
+#define ACPI_GIC_CPU_IF_MEM_SIZE (SZ_8K)
+#define ACPI_GICV3_DIST_MEM_SIZE (SZ_64K)
+#define ACPI_GICV3_ITS_MEM_SIZE (SZ_128K)
+
+static int gic_acpi_version(struct acpi_subtable_header *header)
+{
+ struct acpi_madt_generic_distributor *dist = (void *)header;
+ int version = dist->version;
+
+ if (version == 2)
+ gic_common_ops = &gicv2_common_ops;
+ else if (version == 3)
+ gic_common_ops = &gicv3_common_ops;
+
+ return version;
+}
+
+static int gicv2_acpi_parse_madt_cpu(struct acpi_subtable_header *header)
+{
+ struct acpi_madt_generic_interrupt *gicc = (void *)header;
+ static phys_addr_t gicc_base_address;
+
+ if (!(gicc->flags & ACPI_MADT_ENABLED))
+ return 0;
+
+ if (!gicc_base_address) {
+ gicc_base_address = gicc->base_address;
+ gicv2_data.cpu_base = ioremap(gicc_base_address, ACPI_GIC_CPU_IF_MEM_SIZE);
+ }
+ assert(gicc_base_address == gicc->base_address);
+
+ return 0;
+}
+
+static int gicv2_acpi_parse_madt_dist(struct acpi_subtable_header *header)
+{
+ struct acpi_madt_generic_distributor *dist = (void *)header;
+
+ gicv2_data.dist_base = ioremap(dist->base_address, ACPI_GICV2_DIST_MEM_SIZE);
+
+ return 0;
+}
+
+static int gicv3_acpi_parse_madt_gicc(struct acpi_subtable_header *header)
+{
+ struct acpi_madt_generic_interrupt *gicc = (void *)header;
+ static phys_addr_t gicr_base_address;
+
+ if (!(gicc->flags & ACPI_MADT_ENABLED))
+ return 0;
+
+ if (!gicr_base_address) {
+ gicr_base_address = gicc->gicr_base_address;
+ gicv3_data.redist_bases[0] = ioremap(gicr_base_address, SZ_64K * 2);
+ }
+ assert(gicr_base_address == gicc->gicr_base_address);
+
+ return 0;
+}
+
+static int gicv3_acpi_parse_madt_dist(struct acpi_subtable_header *header)
+{
+ struct acpi_madt_generic_distributor *dist = (void *)header;
+
+ gicv3_data.dist_base = ioremap(dist->base_address, ACPI_GICV3_DIST_MEM_SIZE);
+
+ return 0;
+}
+
+static int gicv3_acpi_parse_madt_redist(struct acpi_subtable_header *header)
+{
+ static int i;
+ struct acpi_madt_generic_redistributor *redist = (void *)header;
+
+ gicv3_data.redist_bases[i++] = ioremap(redist->base_address, redist->length);
+
+ return 0;
+}
+
+static int gicv3_acpi_parse_madt_its(struct acpi_subtable_header *header)
+{
+ struct acpi_madt_generic_translator *its_entry = (void *)header;
+
+ its_data.base = ioremap(its_entry->base_address, ACPI_GICV3_ITS_MEM_SIZE - 1);
+
+ return 0;
+}
+
+static int gic_init_acpi(void)
+{
+ int count;
+
+ acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR, gic_acpi_version);
+ if (gic_version() == 2) {
+ acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
+ gicv2_acpi_parse_madt_cpu);
+ acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
+ gicv2_acpi_parse_madt_dist);
+ } else if (gic_version() == 3) {
+ acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
+ gicv3_acpi_parse_madt_dist);
+ count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR,
+ gicv3_acpi_parse_madt_redist);
+ if (!count)
+ acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
+ gicv3_acpi_parse_madt_gicc);
+ acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR,
+ gicv3_acpi_parse_madt_its);
+#ifdef __aarch64__
+ its_init();
+#endif
+ }
+
+ return gic_version();
+}
+
+#else
+
+static int gic_init_acpi(void)
+{
+ assert_msg(false, "ACPI not available");
+}
+
+#endif /* CONFIG_EFI */
+
+int gic_init(void)
+{
+ if (dt_available())
+ return gic_init_fdt();
+ else
+ return gic_init_acpi();
+}
+
void gic_enable_defaults(void)
{
if (!gic_common_ops) {
diff --git a/lib/libcflat.h b/lib/libcflat.h
index c1fd31ff..700f4352 100644
--- a/lib/libcflat.h
+++ b/lib/libcflat.h
@@ -161,6 +161,7 @@ extern void setup_vm(void);
#define SZ_8K (1 << 13)
#define SZ_16K (1 << 14)
#define SZ_64K (1 << 16)
+#define SZ_128K (1 << 17)
#define SZ_1M (1 << 20)
#define SZ_2M (1 << 21)
#define SZ_1G (1 << 30)
--
2.25.1
next prev parent reply other threads:[~2023-02-13 10:18 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-02-13 10:17 [PATCH v4 00/30] EFI and ACPI support for arm64 Nikos Nikoleris
2023-02-13 10:17 ` [PATCH v4 01/30] lib: Move acpi header and implementation to lib Nikos Nikoleris
2023-02-13 10:17 ` [PATCH v4 02/30] x86: Move x86_64-specific EFI CFLAGS to x86_64 Makefile Nikos Nikoleris
2023-02-13 10:17 ` [PATCH v4 03/30] arm/Makefile.common: Compile lib/acpi.c if CONFIG_EFI=y Nikos Nikoleris
2023-02-13 10:17 ` [PATCH v4 04/30] lib: Apply Lindent to acpi.{c,h} Nikos Nikoleris
2023-03-09 7:11 ` Shaoqin Huang
2023-03-21 17:32 ` Andrew Jones
2023-03-22 10:05 ` Nikos Nikoleris
2023-02-13 10:17 ` [PATCH v4 05/30] lib: Fix style for acpi.{c,h} Nikos Nikoleris
2023-02-13 10:17 ` [PATCH v4 06/30] lib/acpi: Convert table names to Linux style Nikos Nikoleris
2023-02-13 10:17 ` [PATCH v4 07/30] x86: Avoid references to fields of ACPI tables Nikos Nikoleris
2023-02-13 10:17 ` [PATCH v4 08/30] lib/acpi: Ensure all struct definition for ACPI tables are packed Nikos Nikoleris
2023-02-13 10:17 ` [PATCH v4 09/30] lib/acpi: Add support for the XSDT table Nikos Nikoleris
2023-02-13 10:17 ` [PATCH v4 10/30] lib/acpi: Extend the definition of the FADT table Nikos Nikoleris
2023-02-13 10:17 ` [PATCH v4 11/30] devicetree: Check that fdt is not NULL in dt_available() Nikos Nikoleris
2023-02-13 10:17 ` [PATCH v4 12/30] arm64: Add support for setting up the PSCI conduit through ACPI Nikos Nikoleris
2023-03-21 17:31 ` Andrew Jones
2023-02-13 10:17 ` [PATCH v4 13/30] arm64: Add support for discovering the UART " Nikos Nikoleris
2023-02-13 10:17 ` [PATCH v4 14/30] arm64: Add support for timer initialization " Nikos Nikoleris
2023-02-13 10:17 ` [PATCH v4 15/30] arm64: Add support for cpu " Nikos Nikoleris
2023-02-13 10:17 ` Nikos Nikoleris [this message]
2023-03-30 6:46 ` [PATCH v4 16/30] arm64: Add support for gic " Shaoqin Huang
2023-02-13 10:17 ` [PATCH v4 17/30] lib/printf: Support for precision modifier in printf Nikos Nikoleris
2023-02-13 10:17 ` [PATCH v4 18/30] lib/printf: Add support for printing wide strings Nikos Nikoleris
2023-02-13 10:17 ` [PATCH v4 19/30] lib/efi: Add support for getting the cmdline Nikos Nikoleris
2023-02-13 10:17 ` [PATCH v4 20/30] arm/arm64: Rename etext to _etext Nikos Nikoleris
2023-02-13 10:17 ` [PATCH v4 21/30] lib: Avoid ms_abi for calls related to EFI on arm64 Nikos Nikoleris
2023-02-13 10:17 ` [PATCH v4 22/30] arm64: Add a new type of memory type flag MR_F_RESERVED Nikos Nikoleris
2023-02-13 10:17 ` [PATCH v4 23/30] arm64: Add a setup sequence for systems that boot through EFI Nikos Nikoleris
2023-04-25 7:04 ` Shaoqin Huang
2023-04-25 9:09 ` Nikos Nikoleris
2023-04-25 18:31 ` Andrew Jones
2023-02-13 10:17 ` [PATCH v4 24/30] arm64: Copy code from GNU-EFI Nikos Nikoleris
2023-02-13 10:17 ` [PATCH v4 25/30] arm64: Change GNU-EFI imported code to use defined types Nikos Nikoleris
2023-03-30 6:49 ` Shaoqin Huang
2023-02-13 10:17 ` [PATCH v4 26/30] arm64: Use code from the gnu-efi when booting with EFI Nikos Nikoleris
2023-02-13 10:17 ` [PATCH v4 27/30] lib: Avoid external dependency in libelf Nikos Nikoleris
2023-02-13 10:17 ` [PATCH v4 28/30] arm64: Add support for efi in Makefile Nikos Nikoleris
2023-03-21 18:21 ` Andrew Jones
2023-02-13 10:17 ` [PATCH v4 29/30] lib: arm: Print test exit status Nikos Nikoleris
2023-02-13 10:17 ` [PATCH v4 30/30] arm64: Add an efi/run script Nikos Nikoleris
2023-03-21 18:41 ` Andrew Jones
2023-03-22 10:02 ` Nikos Nikoleris
2023-03-22 11:24 ` Andrew Jones
2023-03-22 11:57 ` Nikos Nikoleris
2023-03-22 12:32 ` Andrew Jones
2023-03-22 19:09 ` Nikos Nikoleris
2023-03-23 17:52 ` Andrew Jones
2023-03-28 9:03 ` Alexandru Elisei
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230213101759.2577077-17-nikos.nikoleris@arm.com \
--to=nikos.nikoleris@arm.com \
--cc=alexandru.elisei@arm.com \
--cc=andrew.jones@linux.dev \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.linux.dev \
--cc=pbonzini@redhat.com \
--cc=ricarkol@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.