From: Mohamed Mediouni <mohamed.mediouni@caramail.com>
To: linux-arm-kernel@lists.infradead.org
Cc: Mark Rutland <mark.rutland@arm.com>,
Catalin Marinas <catalin.marinas@arm.com>,
Hector Martin <marcan@marcan.st>,
linux-kernel@vger.kernel.org, Marc Zyngier <maz@kernel.org>,
Mohamed Mediouni <mohamed.mediouni@caramail.com>,
Will Deacon <will@kernel.org>,
Stan Skowronek <stan@corellium.com>
Subject: [RFC PATCH 6/7] arm64: kernel: Apple CPU start driver
Date: Wed, 20 Jan 2021 14:27:16 +0100 [thread overview]
Message-ID: <20210120132717.395873-7-mohamed.mediouni@caramail.com> (raw)
In-Reply-To: <20210120132717.395873-1-mohamed.mediouni@caramail.com>
From: Stan Skowronek <stan@corellium.com>
This driver is needed to spawn CPUs for SMP
on Apple Silicon platforms.
Signed-off-by: Stan Skowronek <stan@corellium.com>
Signed-off-by: Mohamed Mediouni <mohamed.mediouni@caramail.com>
---
.../devicetree/bindings/arm/cpus.yaml | 1 +
arch/arm64/kernel/Makefile | 1 +
arch/arm64/kernel/apple_cpustart.c | 153 ++++++++++++++++++
3 files changed, 155 insertions(+)
create mode 100644 arch/arm64/kernel/apple_cpustart.c
diff --git a/Documentation/devicetree/bindings/arm/cpus.yaml b/Documentation/devicetree/bindings/arm/cpus.yaml
index 14cd727d3c4b..a6ff8cb3db1e 100644
--- a/Documentation/devicetree/bindings/arm/cpus.yaml
+++ b/Documentation/devicetree/bindings/arm/cpus.yaml
@@ -176,6 +176,7 @@ properties:
oneOf:
# On ARM v8 64-bit this property is required
- enum:
+ - apple
- psci
- spin-table
# On ARM 32-bit systems this property is optional
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 86364ab6f13f..497f43ca7f0f 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_ARM64_RELOC_TEST) += arm64-reloc-test.o
arm64-reloc-test-y := reloc_test_core.o reloc_test_syms.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_CRASH_CORE) += crash_core.o
+obj-$(CONFIG_ARCH_APPLE) += apple_cpustart.o
obj-$(CONFIG_ARM_SDE_INTERFACE) += sdei.o
obj-$(CONFIG_ARM64_PTR_AUTH) += pointer_auth.o
obj-$(CONFIG_ARM64_MTE) += mte.o
diff --git a/arch/arm64/kernel/apple_cpustart.c b/arch/arm64/kernel/apple_cpustart.c
new file mode 100644
index 000000000000..41d049eaaec7
--- /dev/null
+++ b/arch/arm64/kernel/apple_cpustart.c
@@ -0,0 +1,153 @@
+/* SPDX-License-Identifier: (GPL-2.0 or BSD-3-Clause) */
+/*
+ * Copyright (C) 2020 Corellium LLC
+ */
+
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/smp.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+
+#include <asm/cpu_ops.h>
+#include <asm/errno.h>
+#include <asm/smp_plat.h>
+#include <asm/io.h>
+
+#define MAGIC_UNLOCK 0xc5acce55
+
+struct cpu_apple_start_info {
+ void __iomem *pmgr_start;
+ u64 pmgr_start_size;
+ void __iomem *cputrc_rvbar;
+ void __iomem *dbg_unlock;
+};
+
+extern void apple_aic_cpu_prepare(unsigned int cpu);
+
+static int cpu_apple_start0_unlocked = 0;
+static DEFINE_PER_CPU(struct cpu_apple_start_info, cpu_apple_start_info);
+
+static int __init cpu_apple_start_init(unsigned int cpu)
+{
+ return 0;
+}
+
+static int cpu_apple_start_prepare(unsigned int cpu)
+{
+ struct device_node *node;
+ struct cpu_apple_start_info *info;
+
+ info = per_cpu_ptr(&cpu_apple_start_info, cpu);
+
+ if (info->pmgr_start && info->cputrc_rvbar && info->dbg_unlock)
+ return 0;
+
+ node = of_find_compatible_node(NULL, NULL, "apple,startcpu");
+ if (!node) {
+ pr_err("%s: missing startcpu node in device tree.\n", __func__);
+ return -EINVAL;
+ }
+
+ if (!info->pmgr_start) {
+ info->pmgr_start = of_iomap(node, cpu * 3);
+ if (!info->pmgr_start) {
+ pr_err("%s: failed to map start register for CPU %d.\n",
+ __func__, cpu);
+ return -EINVAL;
+ }
+ if (!of_get_address(node, cpu * 3, &info->pmgr_start_size,
+ NULL))
+ info->pmgr_start_size = 8;
+ }
+
+ if (!info->cputrc_rvbar) {
+ info->cputrc_rvbar = of_iomap(node, cpu * 3 + 1);
+ if (!info->cputrc_rvbar) {
+ pr_err("%s: failed to map reset address register for CPU %d.\n",
+ __func__, cpu);
+ return -EINVAL;
+ }
+ }
+
+ if (!info->dbg_unlock) {
+ info->dbg_unlock = of_iomap(node, cpu * 3 + 2);
+ if (!info->dbg_unlock) {
+ pr_err("%s: failed to map unlock register for CPU %d.\n",
+ __func__, cpu);
+ return -EINVAL;
+ }
+ }
+
+ if (cpu)
+ apple_aic_cpu_prepare(cpu);
+
+ return 0;
+}
+
+static int cpu_apple_start_boot(unsigned int cpu)
+{
+ struct cpu_apple_start_info *info;
+ unsigned long addr;
+
+ if (!cpu_apple_start0_unlocked) {
+ if (!cpu_apple_start_prepare(0)) {
+ info = per_cpu_ptr(&cpu_apple_start_info, 0);
+ writel(MAGIC_UNLOCK, info->dbg_unlock);
+ cpu_apple_start0_unlocked = 1;
+ } else
+ pr_err("%s: failed to unlock boot CPU\n", __func__);
+ }
+
+ info = per_cpu_ptr(&cpu_apple_start_info, cpu);
+
+ if (!info->pmgr_start || !info->cputrc_rvbar || !info->dbg_unlock)
+ return -EINVAL;
+
+ writeq(__pa_symbol(secondary_entry) | 1, info->cputrc_rvbar);
+ readq(info->cputrc_rvbar);
+ writeq(__pa_symbol(secondary_entry) | 1, info->cputrc_rvbar);
+ addr = readq(info->cputrc_rvbar) & 0xFFFFFFFFFul;
+ dsb(sy);
+
+ if (addr != (__pa_symbol(secondary_entry) | 1))
+ pr_err("%s: CPU%d reset address: 0x%lx, failed to set to 0x%lx.\n",
+ __func__, cpu, addr,
+ (unsigned long)(__pa_symbol(secondary_entry) | 1));
+
+ writel(MAGIC_UNLOCK, info->dbg_unlock);
+
+ writel(1 << cpu, info->pmgr_start);
+ if (info->pmgr_start_size >= 12) {
+ if (cpu < 4) {
+ writel(1 << cpu, info->pmgr_start + 4);
+ writel(0, info->pmgr_start + 8);
+ } else {
+ writel(0, info->pmgr_start + 4);
+ writel(1 << (cpu - 4), info->pmgr_start + 8);
+ }
+ } else
+ writel(1 << cpu, info->pmgr_start + 4);
+
+ dsb(sy);
+ sev();
+
+ return 0;
+}
+
+static void cpu_apple_wfi(void)
+{
+ /* can't do a proper WFI, because the CPU tends to lose state; will need
+ a proper wrapper sequence */
+ dsb(sy);
+ wfe();
+}
+
+const struct cpu_operations cpu_apple_start_ops = {
+ .name = "apple",
+ .cpu_init = cpu_apple_start_init,
+ .cpu_prepare = cpu_apple_start_prepare,
+ .cpu_boot = cpu_apple_start_boot,
+ .cpu_wfi = cpu_apple_wfi,
+};
--
2.29.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2021-01-20 13:31 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-20 13:27 [RFC PATCH 0/7] Linux on Apple Silicon Mohamed Mediouni
2021-01-20 13:27 ` [RFC PATCH 1/7] arm64: kernel: FIQ support Mohamed Mediouni
2021-01-20 13:27 ` [RFC PATCH 2/7] arm64: kernel: Add a WFI hook Mohamed Mediouni
2021-01-20 16:46 ` Alexander Graf
[not found] ` <94C20F55-D3B8-4349-B26F-9EA8AAEBF639@caramail.com>
2021-01-21 12:33 ` Hector Martin 'marcan'
2021-01-21 10:52 ` Arnd Bergmann
2021-01-21 11:01 ` Mohamed Mediouni
2021-01-21 11:36 ` Arnd Bergmann
2021-01-20 13:27 ` [RFC PATCH 3/7] arm64: mm: use nGnRnE instead of nGnRE on Apple processors Mohamed Mediouni
2021-01-20 16:47 ` Alexander Graf
2021-01-20 18:06 ` Mohamed Mediouni
2021-01-20 18:10 ` Alexander Graf
2021-01-21 11:27 ` Will Deacon
2021-01-21 11:38 ` Arnd Bergmann
2021-01-21 11:44 ` Marc Zyngier
2021-01-21 12:47 ` Will Deacon
2021-01-21 15:12 ` Mohamed Mediouni
2021-01-21 16:25 ` Marc Zyngier
2021-01-21 17:55 ` Will Deacon
2021-01-21 18:15 ` Marc Zyngier
2021-01-21 18:22 ` Mohamed Mediouni
2021-01-21 18:22 ` Will Deacon
2021-01-20 13:27 ` [RFC PATCH 4/7] irqchip/apple-aic: Add support for Apple AIC Mohamed Mediouni
2021-01-20 17:11 ` Alexander Graf
2021-01-20 18:04 ` Mohamed Mediouni
2021-01-20 20:16 ` Andrew Lunn
2021-01-20 21:18 ` Stan Skowronek
2021-01-21 9:48 ` Linus Walleij
2021-01-21 10:37 ` Arnd Bergmann
2021-01-21 15:29 ` Hector Martin 'marcan'
2021-01-21 17:09 ` Rob Herring
2021-01-21 17:45 ` Rob Herring
2021-01-21 16:44 ` Rob Herring
2021-01-21 16:53 ` Hector Martin 'marcan'
2021-01-20 13:27 ` [RFC PATCH 5/7] arm64/Kconfig: Add Apple Silicon SoC platform Mohamed Mediouni
2021-01-20 13:27 ` Mohamed Mediouni [this message]
2021-01-21 11:14 ` [RFC PATCH 6/7] arm64: kernel: Apple CPU start driver Arnd Bergmann
2021-01-20 13:27 ` [RFC PATCH 7/7] irqchip/apple-aic: add SMP support to the Apple AIC driver Mohamed Mediouni
2021-01-21 12:44 ` Arnd Bergmann
2021-01-21 12:50 ` Mohamed Mediouni
2021-01-21 13:00 ` Arnd Bergmann
2021-01-21 13:01 ` Hector Martin 'marcan'
2021-01-21 13:22 ` Marc Zyngier
2021-01-21 13:32 ` Mark Rutland
2021-01-21 14:05 ` Marc Zyngier
2021-01-21 13:34 ` Mohamed Mediouni
2021-01-21 14:10 ` Marc Zyngier
2021-01-21 15:09 ` Arnd Bergmann
2021-01-21 15:18 ` Mohamed Mediouni
2021-01-21 16:40 ` Rob Herring
2021-01-21 16:43 ` Mohamed Mediouni
2021-01-21 17:37 ` Rob Herring
2021-01-21 18:08 ` Mohamed Mediouni
2021-01-21 18:57 ` Rob Herring
2021-02-02 19:15 ` Linus Walleij
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=20210120132717.395873-7-mohamed.mediouni@caramail.com \
--to=mohamed.mediouni@caramail.com \
--cc=catalin.marinas@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=marcan@marcan.st \
--cc=mark.rutland@arm.com \
--cc=maz@kernel.org \
--cc=stan@corellium.com \
--cc=will@kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).