From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f43.google.com (mail-wm1-f43.google.com [209.85.128.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4BAFA1E2018 for ; Wed, 2 Oct 2024 09:52:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.43 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727862751; cv=none; b=brjyvvjqapUPuayzci46efJvDqwNmZwOmU+k5Ft7bdUcgobSuliCjt973fiL/5/03idTWNMJ7MQFN5DjAqPhHRqhp28H4njbvGmNbqXT07c08inAsvYC/8LnDVbGxCBKz7TKRYKHidgACxEwHCdsdNgGUfIb5/C00u0kER4TtmQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727862751; c=relaxed/simple; bh=ULPS3rx2Rggy2xdUN3QBRwGtRUeMuF6InxvyLJX6C/k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IifZE4LqcVp7MD5l//5X6KQZw9DKJ0sC9FoGzr0KGBgRlFOh2g5TSCyHZ3AHNI87ZvSdMbxOSzNvTdBmjaa8Yfc8zZWv6td5FSpXcfy0MPwdA2Afw13LuP+XXDJJJy9GcmC8VRjAzqLD45epTo/CRiid1TVbkR5alNdxTdSOswc= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=9elements.com; spf=pass smtp.mailfrom=9elements.com; dkim=pass (2048-bit key) header.d=9elements.com header.i=@9elements.com header.b=WRdFF5Dp; arc=none smtp.client-ip=209.85.128.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=9elements.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=9elements.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=9elements.com header.i=@9elements.com header.b="WRdFF5Dp" Received: by mail-wm1-f43.google.com with SMTP id 5b1f17b1804b1-42e5e758093so52565135e9.1 for ; Wed, 02 Oct 2024 02:52:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=9elements.com; s=google; t=1727862748; x=1728467548; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=xrQY2+xb+lugKHBRrv4kxIlkaNKcIVXX7vgDt2h2bH8=; b=WRdFF5DpE+ta5SHqpH1D9Jh6TbG7WVMpsW7zCTCAPCFgsA7AcQPFw2HxGS9KYdTFEn 7KqJr16Hl9OH1RKMsxM6fQ4sDXPu4a9ZuXPbcZrKyZJbiQRpS/ZghP9I9Bbyr6yo9LOc tgQTLQrzCWVtdo8lfk0fBf90b6uE0CXTd7vt0WbTpz/4vG9FOXaTsdlC9w8h4KPqPLe5 8YwkZu+yFH5e2T5Y73JVXF9l16xnak278ZU6msixktDymnVQELv/Qxh6pWwBmgWCmCiw VHcye0Dyt/kCixbyk4IRg//zDq+NbBR3d4f2Btx1KUELKdViX9JR592EeJr+XTUNNTzR DEJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727862748; x=1728467548; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=xrQY2+xb+lugKHBRrv4kxIlkaNKcIVXX7vgDt2h2bH8=; b=iShhbpFXwFlKeupkiUWfH8emABuFFukmyMI+mZxJkg82mTxdeuQ4j4Wdtm3JM4K4kU 9iB1LXTtmI0DX3tNXDUeOD/CPf/mD1bQKXT/c+6UMsYQuZcx29YZF7T/x79bKDpCrNJm 8kaisFhGSi0NhNLSoqw0fKQnZSsZwMtvY1Pyw300k/g7WZA5DWKy3EMV4GoXri8J3lnE Tts6bxnzUJYmCWP7/IC+AHIJIrG3SaUMArmsIwNpPk7L/cZi1zwe+9sbIQAWhu1wvfKh YCu7F1Xem2kB06kLmxSM0DIFGViOX/xCBRnFBHri1bqq4TPhXDytvKjk8gHk71aFeFem FXKQ== X-Forwarded-Encrypted: i=1; AJvYcCXwjQPGeo6O1K1NQL14NUaP0S5enqdgyACm/YGEed/lbxTpmn+rVRZ4FvLMZDsK3Ws02gw+zuPHyjEj7tg=@vger.kernel.org X-Gm-Message-State: AOJu0Yy+IcsReVRUUn5u6HlKvfODXNV2jhqotAHv511kn/wzNu1UfXIX KS1RDz4KegZ4WQynIXwBSnYeFwwAiF6zNf0O3DzRbtQn5/kafgvcukLL8LmUoaoyIfOXEakcsu+ k X-Google-Smtp-Source: AGHT+IF9tj8g45Ku/ACycnuBcsnVUT63TLbgbpciZfbM6ulmIRcoZS4a9vvfPFy5nC/uO31x5yX6Pw== X-Received: by 2002:a5d:444c:0:b0:37c:cc77:3e72 with SMTP id ffacd0b85a97d-37cfb9c53e8mr1347708f8f.33.1727862747689; Wed, 02 Oct 2024 02:52:27 -0700 (PDT) Received: from fedora.sec.9e.network (ip-078-094-000-050.um19.pools.vodafone-ip.de. [78.94.0.50]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-37cd56e94c4sm13555292f8f.62.2024.10.02.02.52.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 02 Oct 2024 02:52:27 -0700 (PDT) From: Patrick Rudolph To: u-boot@lists.denx.de, linux-kernel@vger.kernel.org Cc: Patrick Rudolph , Simon Glass , Tom Rini Subject: [PATCH v6 23/37] drivers/arm: Implement acpi_fill_madt Date: Wed, 2 Oct 2024 11:47:14 +0200 Message-ID: <20241002094832.24933-24-patrick.rudolph@9elements.com> X-Mailer: git-send-email 2.46.2 In-Reply-To: <20241002094832.24933-1-patrick.rudolph@9elements.com> References: <20241002094832.24933-1-patrick.rudolph@9elements.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Fill the MADT table in the GIC driver and armv8 CPU driver to drop SoC specific code. While the GIC only needs devicetree data, the CPU driver needs additional information stored in the cpu_plat struct. While on it update the only board making use of the existing drivers and writing ACPI MADT in mainboard code. TEST: Booted on QEMU sbsa-ref using GICV3 driver model generated MADT. Booted on QEMU raspb4 using GICV2 driver model generated MADT. Signed-off-by: Patrick Rudolph Reviewed-by: Simon Glass Cc: Simon Glass --- Changelog v4: - Read everything from the DT - Export armv8_cpu_fill_madt() to use it in other CPU drivers - Depend on IRQ Changelog v6: - Update header order --- arch/arm/lib/gic-v3-its.c | 89 ++++++++++++++++++++++++++++++++++++++- drivers/cpu/Kconfig | 1 + drivers/cpu/armv8_cpu.c | 80 ++++++++++++++++++++++++++++++++++- drivers/cpu/armv8_cpu.h | 10 +++++ 4 files changed, 178 insertions(+), 2 deletions(-) diff --git a/arch/arm/lib/gic-v3-its.c b/arch/arm/lib/gic-v3-its.c index 0d5545bfb2..ad1c3d7312 100644 --- a/arch/arm/lib/gic-v3-its.c +++ b/arch/arm/lib/gic-v3-its.c @@ -5,9 +5,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -27,12 +29,14 @@ static u32 lpi_id_bits; struct gic_v3_its_priv { ulong gicd_base; ulong gicr_base; + ulong gicr_length; }; static int gic_v3_its_get_gic_addr(struct gic_v3_its_priv *priv) { struct udevice *dev; fdt_addr_t addr; + fdt_size_t size; int ret; ret = uclass_get_device_by_driver(UCLASS_IRQ, @@ -50,12 +54,13 @@ static int gic_v3_its_get_gic_addr(struct gic_v3_its_priv *priv) } priv->gicd_base = addr; - addr = dev_read_addr_index(dev, 1); + addr = dev_read_addr_size_index(dev, 1, &size); if (addr == FDT_ADDR_T_NONE) { pr_err("%s: failed to get GICR address\n", __func__); return -EINVAL; } priv->gicr_base = addr; + priv->gicr_length = size; return 0; } @@ -159,6 +164,42 @@ int gic_lpi_tables_init(u64 base, u32 num_redist) return 0; } +#ifdef CONFIG_ACPIGEN +/** + * acpi_gicv3_fill_madt() - Fill out the body of the MADT + * + * Write GICD and GICR tables based on collected devicetree data. + * + * @dev: Device to write ACPI tables for + * @ctx: ACPI context to write MADT sub-tables to + * Return: 0 if OK + */ +static int acpi_gicv3_fill_madt(const struct udevice *dev, struct acpi_ctx *ctx) +{ + struct acpi_madt_gicd *gicd; + struct acpi_madt_gicr *gicr; + + struct gic_v3_its_priv priv; + + if (gic_v3_its_get_gic_addr(&priv)) + return -EINVAL; + + gicd = ctx->current; + acpi_write_madt_gicd(gicd, dev_seq(dev), priv.gicd_base, 3); + acpi_inc(ctx, gicd->length); + + gicr = ctx->current; + acpi_write_madt_gicr(gicr, priv.gicr_base, priv.gicr_length); + acpi_inc(ctx, gicr->length); + + return 0; +} + +struct acpi_ops gic_v3_acpi_ops = { + .fill_madt = acpi_gicv3_fill_madt, +}; +#endif + static const struct udevice_id gic_v3_ids[] = { { .compatible = "arm,gic-v3" }, {} @@ -188,4 +229,50 @@ U_BOOT_DRIVER(arm_gic_v3) = { .id = UCLASS_IRQ, .of_match = gic_v3_ids, .ops = &arm_gic_v3_ops, + ACPI_OPS_PTR(&gic_v3_acpi_ops) +}; + +#ifdef CONFIG_ACPIGEN +/** + * acpi_gic_its_fill_madt() - Fill out the body of the MADT + * + * Write ITS tables based on collected devicetree data. + * + * @dev: Device to write ACPI tables for + * @ctx: ACPI context to write MADT sub-tables to + * Return: 0 if OK + */ +static int acpi_gic_its_fill_madt(const struct udevice *dev, struct acpi_ctx *ctx) +{ + struct acpi_madt_its *its; + fdt_addr_t addr; + + addr = dev_read_addr_index(dev, 0); + if (addr == FDT_ADDR_T_NONE) { + pr_err("%s: failed to get GIC ITS address\n", __func__); + return -EINVAL; + } + + its = ctx->current; + acpi_write_madt_its(its, dev_seq(dev), addr); + acpi_inc(ctx, its->length); + + return 0; +} + +struct acpi_ops gic_v3_its_acpi_ops = { + .fill_madt = acpi_gic_its_fill_madt, +}; +#endif + +static const struct udevice_id gic_v3_its_ids[] = { + { .compatible = "arm,gic-v3-its" }, + {} +}; + +U_BOOT_DRIVER(arm_gic_v3_its) = { + .name = "gic-v3-its", + .id = UCLASS_IRQ, + .of_match = gic_v3_its_ids, + ACPI_OPS_PTR(&gic_v3_its_acpi_ops) }; diff --git a/drivers/cpu/Kconfig b/drivers/cpu/Kconfig index 9c0df331d7..4cc3679c00 100644 --- a/drivers/cpu/Kconfig +++ b/drivers/cpu/Kconfig @@ -29,6 +29,7 @@ config CPU_RISCV config CPU_ARMV8 bool "Enable generic ARMv8 CPU driver" depends on CPU && ARM64 + select IRQ help Support CPU cores for armv8 architecture. diff --git a/drivers/cpu/armv8_cpu.c b/drivers/cpu/armv8_cpu.c index 19f072be43..4eedfe5e2c 100644 --- a/drivers/cpu/armv8_cpu.c +++ b/drivers/cpu/armv8_cpu.c @@ -4,10 +4,11 @@ */ #include #include +#include #include #include -#include #include +#include #include #include #include @@ -47,8 +48,85 @@ int armv8_cpu_fill_ssdt(const struct udevice *dev, struct acpi_ctx *ctx) return 0; } +int armv8_cpu_fill_madt(const struct udevice *dev, struct acpi_ctx *ctx) +{ + struct acpi_madt_gicc *gicc; + struct cpu_plat *cpu_plat; + struct udevice *gic; + u64 gicc_gicv = 0; + u64 gicc_gich = 0; + u64 gicc_gicr_base = 0; + u64 gicc_phys_base = 0; + u32 gicc_perf_gsiv = 0; + u64 gicc_mpidr; + u32 gicc_vgic_maint_irq = 0; + int addr_index; + fdt_addr_t addr; + int ret; + struct irq req_irq; + + cpu_plat = dev_get_parent_plat(dev); + if (!cpu_plat) + return 0; + + ret = irq_get_interrupt_parent(dev, &gic); + if (ret) { + log_err("%s: Failed to find interrupt parent for %s\n", + __func__, dev->name); + return -ENODEV; + } + + addr_index = 1; + + if (device_is_compatible(gic, "arm,gic-v3")) { + addr = dev_read_addr_index(gic, addr_index++); + if (addr != FDT_ADDR_T_NONE) + gicc_gicr_base = addr; + } + + addr = dev_read_addr_index(gic, addr_index++); + if (addr != FDT_ADDR_T_NONE) + gicc_phys_base = addr; + + addr = dev_read_addr_index(gic, addr_index++); + if (addr != FDT_ADDR_T_NONE) + gicc_gich = addr; + + addr = dev_read_addr_index(gic, addr_index++); + if (addr != FDT_ADDR_T_NONE) + gicc_gicv = addr; + + ret = irq_get_by_index(gic, 0, &req_irq); + if (!ret) + gicc_vgic_maint_irq = req_irq.id; + + gicc_mpidr = dev_read_u64_default(dev, "reg", 0); + if (!gicc_mpidr) + gicc_mpidr = dev_read_u32_default(dev, "reg", 0); + + /* + * gicc_vgic_maint_irq and gicc_gicv are the same for every CPU + */ + gicc = ctx->current; + acpi_write_madt_gicc(gicc, + dev_seq(dev), + gicc_perf_gsiv, /* FIXME: needs a PMU driver */ + gicc_phys_base, + gicc_gicv, + gicc_gich, + gicc_vgic_maint_irq, + gicc_gicr_base, + gicc_mpidr, + 0); /* FIXME: Not defined in DT */ + + acpi_inc(ctx, gicc->length); + + return 0; +} + struct acpi_ops armv8_cpu_acpi_ops = { .fill_ssdt = armv8_cpu_fill_ssdt, + .fill_madt = armv8_cpu_fill_madt, }; #endif diff --git a/drivers/cpu/armv8_cpu.h b/drivers/cpu/armv8_cpu.h index 2c4b0252cf..48c705e98d 100644 --- a/drivers/cpu/armv8_cpu.h +++ b/drivers/cpu/armv8_cpu.h @@ -18,4 +18,14 @@ */ int armv8_cpu_fill_ssdt(const struct udevice *dev, struct acpi_ctx *ctx); +/** + * armv8_cpu_fill_madt() - Fill the MADT + * Parses the FDT and writes the MADT subtables. + * + * @dev: cpu device to generate ACPI tables for + * @ctx: ACPI context pointer + * @return: 0 if OK, or a negative error code. + */ +int armv8_cpu_fill_madt(const struct udevice *dev, struct acpi_ctx *ctx); + #endif \ No newline at end of file -- 2.46.2