platsmp.c (1409B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2// Copyright (C) ASPEED Technology Inc. 3// Copyright IBM Corp. 4 5#include <linux/of_address.h> 6#include <linux/io.h> 7#include <linux/of.h> 8#include <linux/smp.h> 9 10#define BOOT_ADDR 0x00 11#define BOOT_SIG 0x04 12 13static struct device_node *secboot_node; 14 15static int aspeed_g6_boot_secondary(unsigned int cpu, struct task_struct *idle) 16{ 17 void __iomem *base; 18 19 base = of_iomap(secboot_node, 0); 20 if (!base) { 21 pr_err("could not map the secondary boot base!"); 22 return -ENODEV; 23 } 24 25 writel_relaxed(0, base + BOOT_ADDR); 26 writel_relaxed(__pa_symbol(secondary_startup_arm), base + BOOT_ADDR); 27 writel_relaxed((0xABBAAB00 | (cpu & 0xff)), base + BOOT_SIG); 28 29 dsb_sev(); 30 31 iounmap(base); 32 33 return 0; 34} 35 36static void __init aspeed_g6_smp_prepare_cpus(unsigned int max_cpus) 37{ 38 void __iomem *base; 39 40 secboot_node = of_find_compatible_node(NULL, NULL, "aspeed,ast2600-smpmem"); 41 if (!secboot_node) { 42 pr_err("secboot device node found!!\n"); 43 return; 44 } 45 46 base = of_iomap(secboot_node, 0); 47 if (!base) { 48 pr_err("could not map the secondary boot base!"); 49 return; 50 } 51 __raw_writel(0xBADABABA, base + BOOT_SIG); 52 53 iounmap(base); 54} 55 56static const struct smp_operations aspeed_smp_ops __initconst = { 57 .smp_prepare_cpus = aspeed_g6_smp_prepare_cpus, 58 .smp_boot_secondary = aspeed_g6_boot_secondary, 59}; 60 61CPU_METHOD_OF_DECLARE(aspeed_smp, "aspeed,ast2600-smp", &aspeed_smp_ops);