2019-06-03 05:44:50 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
2013-01-02 15:24:22 +00:00
|
|
|
/*
|
|
|
|
* Spin Table SMP initialisation
|
|
|
|
*
|
|
|
|
* Copyright (C) 2013 ARM Ltd.
|
|
|
|
*/
|
|
|
|
|
arm64: factor out spin-table boot method
The arm64 kernel has an internal holding pen, which is necessary for
some systems where we can't bring CPUs online individually and must hold
multiple CPUs in a safe area until the kernel is able to handle them.
The current SMP infrastructure for arm64 is closely coupled to this
holding pen, and alternative boot methods must launch CPUs into the pen,
where they sit before they are launched into the kernel proper.
With PSCI (and possibly other future boot methods), we can bring CPUs
online individually, and need not perform the secondary_holding_pen
dance. Instead, this patch factors the holding pen management code out
to the spin-table boot method code, as it is the only boot method
requiring the pen.
A new entry point for secondaries, secondary_entry is added for other
boot methods to use, which bypasses the holding pen and its associated
overhead when bringing CPUs online. The smp.pen.text section is also
removed, as the pen can live in head.text without problem.
The cpu_operations structure is extended with two new functions,
cpu_boot and cpu_postboot, for bringing a cpu into the kernel and
performing any post-boot cleanup required by a bootmethod (e.g.
resetting the secondary_holding_pen_release to INVALID_HWID).
Documentation is added for cpu_operations.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
2013-10-24 19:30:16 +00:00
|
|
|
#include <linux/delay.h>
|
2013-01-02 15:24:22 +00:00
|
|
|
#include <linux/init.h>
|
|
|
|
#include <linux/of.h>
|
|
|
|
#include <linux/smp.h>
|
2014-07-30 10:59:02 +00:00
|
|
|
#include <linux/types.h>
|
2017-01-10 21:35:49 +00:00
|
|
|
#include <linux/mm.h>
|
2013-01-02 15:24:22 +00:00
|
|
|
|
|
|
|
#include <asm/cacheflush.h>
|
2013-10-24 19:30:15 +00:00
|
|
|
#include <asm/cpu_ops.h>
|
arm64: factor out spin-table boot method
The arm64 kernel has an internal holding pen, which is necessary for
some systems where we can't bring CPUs online individually and must hold
multiple CPUs in a safe area until the kernel is able to handle them.
The current SMP infrastructure for arm64 is closely coupled to this
holding pen, and alternative boot methods must launch CPUs into the pen,
where they sit before they are launched into the kernel proper.
With PSCI (and possibly other future boot methods), we can bring CPUs
online individually, and need not perform the secondary_holding_pen
dance. Instead, this patch factors the holding pen management code out
to the spin-table boot method code, as it is the only boot method
requiring the pen.
A new entry point for secondaries, secondary_entry is added for other
boot methods to use, which bypasses the holding pen and its associated
overhead when bringing CPUs online. The smp.pen.text section is also
removed, as the pen can live in head.text without problem.
The cpu_operations structure is extended with two new functions,
cpu_boot and cpu_postboot, for bringing a cpu into the kernel and
performing any post-boot cleanup required by a bootmethod (e.g.
resetting the secondary_holding_pen_release to INVALID_HWID).
Documentation is added for cpu_operations.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
2013-10-24 19:30:16 +00:00
|
|
|
#include <asm/cputype.h>
|
2015-01-06 00:38:42 +00:00
|
|
|
#include <asm/io.h>
|
arm64: factor out spin-table boot method
The arm64 kernel has an internal holding pen, which is necessary for
some systems where we can't bring CPUs online individually and must hold
multiple CPUs in a safe area until the kernel is able to handle them.
The current SMP infrastructure for arm64 is closely coupled to this
holding pen, and alternative boot methods must launch CPUs into the pen,
where they sit before they are launched into the kernel proper.
With PSCI (and possibly other future boot methods), we can bring CPUs
online individually, and need not perform the secondary_holding_pen
dance. Instead, this patch factors the holding pen management code out
to the spin-table boot method code, as it is the only boot method
requiring the pen.
A new entry point for secondaries, secondary_entry is added for other
boot methods to use, which bypasses the holding pen and its associated
overhead when bringing CPUs online. The smp.pen.text section is also
removed, as the pen can live in head.text without problem.
The cpu_operations structure is extended with two new functions,
cpu_boot and cpu_postboot, for bringing a cpu into the kernel and
performing any post-boot cleanup required by a bootmethod (e.g.
resetting the secondary_holding_pen_release to INVALID_HWID).
Documentation is added for cpu_operations.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
2013-10-24 19:30:16 +00:00
|
|
|
#include <asm/smp_plat.h>
|
|
|
|
|
|
|
|
extern void secondary_holding_pen(void);
|
2020-10-22 02:36:07 +00:00
|
|
|
volatile unsigned long __section(".mmuoff.data.read")
|
2016-08-24 17:27:29 +00:00
|
|
|
secondary_holding_pen_release = INVALID_HWID;
|
2013-01-02 15:24:22 +00:00
|
|
|
|
|
|
|
static phys_addr_t cpu_release_addr[NR_CPUS];
|
arm64: factor out spin-table boot method
The arm64 kernel has an internal holding pen, which is necessary for
some systems where we can't bring CPUs online individually and must hold
multiple CPUs in a safe area until the kernel is able to handle them.
The current SMP infrastructure for arm64 is closely coupled to this
holding pen, and alternative boot methods must launch CPUs into the pen,
where they sit before they are launched into the kernel proper.
With PSCI (and possibly other future boot methods), we can bring CPUs
online individually, and need not perform the secondary_holding_pen
dance. Instead, this patch factors the holding pen management code out
to the spin-table boot method code, as it is the only boot method
requiring the pen.
A new entry point for secondaries, secondary_entry is added for other
boot methods to use, which bypasses the holding pen and its associated
overhead when bringing CPUs online. The smp.pen.text section is also
removed, as the pen can live in head.text without problem.
The cpu_operations structure is extended with two new functions,
cpu_boot and cpu_postboot, for bringing a cpu into the kernel and
performing any post-boot cleanup required by a bootmethod (e.g.
resetting the secondary_holding_pen_release to INVALID_HWID).
Documentation is added for cpu_operations.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
2013-10-24 19:30:16 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Write secondary_holding_pen_release in a way that is guaranteed to be
|
|
|
|
* visible to all observers, irrespective of whether they're taking part
|
|
|
|
* in coherency or not. This is necessary for the hotplug code to work
|
|
|
|
* reliably.
|
|
|
|
*/
|
|
|
|
static void write_pen_release(u64 val)
|
|
|
|
{
|
|
|
|
void *start = (void *)&secondary_holding_pen_release;
|
|
|
|
unsigned long size = sizeof(secondary_holding_pen_release);
|
|
|
|
|
|
|
|
secondary_holding_pen_release = val;
|
arm64: Rename arm64-internal cache maintenance functions
Although naming across the codebase isn't that consistent, it
tends to follow certain patterns. Moreover, the term "flush"
isn't defined in the Arm Architecture reference manual, and might
be interpreted to mean clean, invalidate, or both for a cache.
Rename arm64-internal functions to make the naming internally
consistent, as well as making it consistent with the Arm ARM, by
specifying whether it applies to the instruction, data, or both
caches, whether the operation is a clean, invalidate, or both.
Also specify which point the operation applies to, i.e., to the
point of unification (PoU), coherency (PoC), or persistence
(PoP).
This commit applies the following sed transformation to all files
under arch/arm64:
"s/\b__flush_cache_range\b/caches_clean_inval_pou_macro/g;"\
"s/\b__flush_icache_range\b/caches_clean_inval_pou/g;"\
"s/\binvalidate_icache_range\b/icache_inval_pou/g;"\
"s/\b__flush_dcache_area\b/dcache_clean_inval_poc/g;"\
"s/\b__inval_dcache_area\b/dcache_inval_poc/g;"\
"s/__clean_dcache_area_poc\b/dcache_clean_poc/g;"\
"s/\b__clean_dcache_area_pop\b/dcache_clean_pop/g;"\
"s/\b__clean_dcache_area_pou\b/dcache_clean_pou/g;"\
"s/\b__flush_cache_user_range\b/caches_clean_inval_user_pou/g;"\
"s/\b__flush_icache_all\b/icache_inval_all_pou/g;"
Note that __clean_dcache_area_poc is deliberately missing a word
boundary check at the beginning in order to match the efistub
symbols in image-vars.h.
Also note that, despite its name, __flush_icache_range operates
on both instruction and data caches. The name change here
reflects that.
No functional change intended.
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Fuad Tabba <tabba@google.com>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Link: https://lore.kernel.org/r/20210524083001.2586635-19-tabba@google.com
Signed-off-by: Will Deacon <will@kernel.org>
2021-05-24 08:30:01 +00:00
|
|
|
dcache_clean_inval_poc((unsigned long)start, (unsigned long)start + size);
|
arm64: factor out spin-table boot method
The arm64 kernel has an internal holding pen, which is necessary for
some systems where we can't bring CPUs online individually and must hold
multiple CPUs in a safe area until the kernel is able to handle them.
The current SMP infrastructure for arm64 is closely coupled to this
holding pen, and alternative boot methods must launch CPUs into the pen,
where they sit before they are launched into the kernel proper.
With PSCI (and possibly other future boot methods), we can bring CPUs
online individually, and need not perform the secondary_holding_pen
dance. Instead, this patch factors the holding pen management code out
to the spin-table boot method code, as it is the only boot method
requiring the pen.
A new entry point for secondaries, secondary_entry is added for other
boot methods to use, which bypasses the holding pen and its associated
overhead when bringing CPUs online. The smp.pen.text section is also
removed, as the pen can live in head.text without problem.
The cpu_operations structure is extended with two new functions,
cpu_boot and cpu_postboot, for bringing a cpu into the kernel and
performing any post-boot cleanup required by a bootmethod (e.g.
resetting the secondary_holding_pen_release to INVALID_HWID).
Documentation is added for cpu_operations.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
2013-10-24 19:30:16 +00:00
|
|
|
}
|
|
|
|
|
2013-01-02 15:24:22 +00:00
|
|
|
|
2015-05-13 13:12:46 +00:00
|
|
|
static int smp_spin_table_cpu_init(unsigned int cpu)
|
2013-01-02 15:24:22 +00:00
|
|
|
{
|
2015-05-13 13:12:46 +00:00
|
|
|
struct device_node *dn;
|
2016-04-20 01:23:31 +00:00
|
|
|
int ret;
|
2015-05-13 13:12:46 +00:00
|
|
|
|
|
|
|
dn = of_get_cpu_node(cpu, NULL);
|
|
|
|
if (!dn)
|
|
|
|
return -ENODEV;
|
|
|
|
|
2013-01-02 15:24:22 +00:00
|
|
|
/*
|
|
|
|
* Determine the address from which the CPU is polling.
|
|
|
|
*/
|
2016-04-20 01:23:31 +00:00
|
|
|
ret = of_property_read_u64(dn, "cpu-release-addr",
|
|
|
|
&cpu_release_addr[cpu]);
|
|
|
|
if (ret)
|
2013-01-02 15:24:22 +00:00
|
|
|
pr_err("CPU %d: missing or invalid cpu-release-addr property\n",
|
|
|
|
cpu);
|
|
|
|
|
2016-04-20 01:23:31 +00:00
|
|
|
of_node_put(dn);
|
2013-01-02 15:24:22 +00:00
|
|
|
|
2016-04-20 01:23:31 +00:00
|
|
|
return ret;
|
2013-01-02 15:24:22 +00:00
|
|
|
}
|
|
|
|
|
2013-10-24 19:30:15 +00:00
|
|
|
static int smp_spin_table_cpu_prepare(unsigned int cpu)
|
2013-01-02 15:24:22 +00:00
|
|
|
{
|
2014-07-30 10:59:02 +00:00
|
|
|
__le64 __iomem *release_addr;
|
2021-04-08 18:28:38 +00:00
|
|
|
phys_addr_t pa_holding_pen = __pa_symbol(function_nocfi(secondary_holding_pen));
|
2013-01-02 15:24:22 +00:00
|
|
|
|
|
|
|
if (!cpu_release_addr[cpu])
|
|
|
|
return -ENODEV;
|
|
|
|
|
2014-07-30 10:59:02 +00:00
|
|
|
/*
|
|
|
|
* The cpu-release-addr may or may not be inside the linear mapping.
|
|
|
|
* As ioremap_cache will either give us a new mapping or reuse the
|
|
|
|
* existing linear mapping, we can use it to cover both cases. In
|
|
|
|
* either case the memory will be MT_NORMAL.
|
|
|
|
*/
|
|
|
|
release_addr = ioremap_cache(cpu_release_addr[cpu],
|
|
|
|
sizeof(*release_addr));
|
|
|
|
if (!release_addr)
|
|
|
|
return -ENOMEM;
|
2013-10-11 13:52:18 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* We write the release address as LE regardless of the native
|
2020-08-28 03:18:22 +00:00
|
|
|
* endianness of the kernel. Therefore, any boot-loaders that
|
2013-10-11 13:52:18 +00:00
|
|
|
* read this address need to convert this address to the
|
2020-08-28 03:18:22 +00:00
|
|
|
* boot-loader's endianness before jumping. This is mandated by
|
2013-10-11 13:52:18 +00:00
|
|
|
* the boot protocol.
|
|
|
|
*/
|
2021-04-08 18:28:38 +00:00
|
|
|
writeq_relaxed(pa_holding_pen, release_addr);
|
arm64: Rename arm64-internal cache maintenance functions
Although naming across the codebase isn't that consistent, it
tends to follow certain patterns. Moreover, the term "flush"
isn't defined in the Arm Architecture reference manual, and might
be interpreted to mean clean, invalidate, or both for a cache.
Rename arm64-internal functions to make the naming internally
consistent, as well as making it consistent with the Arm ARM, by
specifying whether it applies to the instruction, data, or both
caches, whether the operation is a clean, invalidate, or both.
Also specify which point the operation applies to, i.e., to the
point of unification (PoU), coherency (PoC), or persistence
(PoP).
This commit applies the following sed transformation to all files
under arch/arm64:
"s/\b__flush_cache_range\b/caches_clean_inval_pou_macro/g;"\
"s/\b__flush_icache_range\b/caches_clean_inval_pou/g;"\
"s/\binvalidate_icache_range\b/icache_inval_pou/g;"\
"s/\b__flush_dcache_area\b/dcache_clean_inval_poc/g;"\
"s/\b__inval_dcache_area\b/dcache_inval_poc/g;"\
"s/__clean_dcache_area_poc\b/dcache_clean_poc/g;"\
"s/\b__clean_dcache_area_pop\b/dcache_clean_pop/g;"\
"s/\b__clean_dcache_area_pou\b/dcache_clean_pou/g;"\
"s/\b__flush_cache_user_range\b/caches_clean_inval_user_pou/g;"\
"s/\b__flush_icache_all\b/icache_inval_all_pou/g;"
Note that __clean_dcache_area_poc is deliberately missing a word
boundary check at the beginning in order to match the efistub
symbols in image-vars.h.
Also note that, despite its name, __flush_icache_range operates
on both instruction and data caches. The name change here
reflects that.
No functional change intended.
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Fuad Tabba <tabba@google.com>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Link: https://lore.kernel.org/r/20210524083001.2586635-19-tabba@google.com
Signed-off-by: Will Deacon <will@kernel.org>
2021-05-24 08:30:01 +00:00
|
|
|
dcache_clean_inval_poc((__force unsigned long)release_addr,
|
2021-05-24 08:29:55 +00:00
|
|
|
(__force unsigned long)release_addr +
|
|
|
|
sizeof(*release_addr));
|
2013-01-02 15:24:22 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Send an event to wake up the secondary CPU.
|
|
|
|
*/
|
|
|
|
sev();
|
|
|
|
|
2014-07-30 10:59:02 +00:00
|
|
|
iounmap(release_addr);
|
|
|
|
|
2013-01-02 15:24:22 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
arm64: factor out spin-table boot method
The arm64 kernel has an internal holding pen, which is necessary for
some systems where we can't bring CPUs online individually and must hold
multiple CPUs in a safe area until the kernel is able to handle them.
The current SMP infrastructure for arm64 is closely coupled to this
holding pen, and alternative boot methods must launch CPUs into the pen,
where they sit before they are launched into the kernel proper.
With PSCI (and possibly other future boot methods), we can bring CPUs
online individually, and need not perform the secondary_holding_pen
dance. Instead, this patch factors the holding pen management code out
to the spin-table boot method code, as it is the only boot method
requiring the pen.
A new entry point for secondaries, secondary_entry is added for other
boot methods to use, which bypasses the holding pen and its associated
overhead when bringing CPUs online. The smp.pen.text section is also
removed, as the pen can live in head.text without problem.
The cpu_operations structure is extended with two new functions,
cpu_boot and cpu_postboot, for bringing a cpu into the kernel and
performing any post-boot cleanup required by a bootmethod (e.g.
resetting the secondary_holding_pen_release to INVALID_HWID).
Documentation is added for cpu_operations.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
2013-10-24 19:30:16 +00:00
|
|
|
static int smp_spin_table_cpu_boot(unsigned int cpu)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Update the pen release flag.
|
|
|
|
*/
|
|
|
|
write_pen_release(cpu_logical_map(cpu));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Send an event, causing the secondaries to read pen_release.
|
|
|
|
*/
|
|
|
|
sev();
|
|
|
|
|
2014-04-04 10:49:05 +00:00
|
|
|
return 0;
|
arm64: factor out spin-table boot method
The arm64 kernel has an internal holding pen, which is necessary for
some systems where we can't bring CPUs online individually and must hold
multiple CPUs in a safe area until the kernel is able to handle them.
The current SMP infrastructure for arm64 is closely coupled to this
holding pen, and alternative boot methods must launch CPUs into the pen,
where they sit before they are launched into the kernel proper.
With PSCI (and possibly other future boot methods), we can bring CPUs
online individually, and need not perform the secondary_holding_pen
dance. Instead, this patch factors the holding pen management code out
to the spin-table boot method code, as it is the only boot method
requiring the pen.
A new entry point for secondaries, secondary_entry is added for other
boot methods to use, which bypasses the holding pen and its associated
overhead when bringing CPUs online. The smp.pen.text section is also
removed, as the pen can live in head.text without problem.
The cpu_operations structure is extended with two new functions,
cpu_boot and cpu_postboot, for bringing a cpu into the kernel and
performing any post-boot cleanup required by a bootmethod (e.g.
resetting the secondary_holding_pen_release to INVALID_HWID).
Documentation is added for cpu_operations.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
2013-10-24 19:30:16 +00:00
|
|
|
}
|
|
|
|
|
2013-10-24 19:30:15 +00:00
|
|
|
const struct cpu_operations smp_spin_table_ops = {
|
2013-01-02 15:24:22 +00:00
|
|
|
.name = "spin-table",
|
2013-10-24 19:30:15 +00:00
|
|
|
.cpu_init = smp_spin_table_cpu_init,
|
|
|
|
.cpu_prepare = smp_spin_table_cpu_prepare,
|
arm64: factor out spin-table boot method
The arm64 kernel has an internal holding pen, which is necessary for
some systems where we can't bring CPUs online individually and must hold
multiple CPUs in a safe area until the kernel is able to handle them.
The current SMP infrastructure for arm64 is closely coupled to this
holding pen, and alternative boot methods must launch CPUs into the pen,
where they sit before they are launched into the kernel proper.
With PSCI (and possibly other future boot methods), we can bring CPUs
online individually, and need not perform the secondary_holding_pen
dance. Instead, this patch factors the holding pen management code out
to the spin-table boot method code, as it is the only boot method
requiring the pen.
A new entry point for secondaries, secondary_entry is added for other
boot methods to use, which bypasses the holding pen and its associated
overhead when bringing CPUs online. The smp.pen.text section is also
removed, as the pen can live in head.text without problem.
The cpu_operations structure is extended with two new functions,
cpu_boot and cpu_postboot, for bringing a cpu into the kernel and
performing any post-boot cleanup required by a bootmethod (e.g.
resetting the secondary_holding_pen_release to INVALID_HWID).
Documentation is added for cpu_operations.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
2013-10-24 19:30:16 +00:00
|
|
|
.cpu_boot = smp_spin_table_cpu_boot,
|
2013-01-02 15:24:22 +00:00
|
|
|
};
|