Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / Atom feed
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
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

  parent reply index

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

Linux-ARM-Kernel Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-arm-kernel/0 linux-arm-kernel/git/0.git
	git clone --mirror https://lore.kernel.org/linux-arm-kernel/1 linux-arm-kernel/git/1.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-arm-kernel linux-arm-kernel/ https://lore.kernel.org/linux-arm-kernel \
		linux-arm-kernel@lists.infradead.org
	public-inbox-index linux-arm-kernel

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.infradead.lists.linux-arm-kernel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git