2012-03-05 11:49:30 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2012 ARM Ltd.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
|
|
* published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
#ifndef __ASM_SMP_H
|
|
|
|
#define __ASM_SMP_H
|
|
|
|
|
2016-02-23 10:31:42 +00:00
|
|
|
/* Values for secondary_data.status */
|
|
|
|
|
|
|
|
#define CPU_MMU_OFF (-1)
|
|
|
|
#define CPU_BOOT_SUCCESS (0)
|
|
|
|
/* The cpu invoked ops->cpu_die, synchronise it with cpu_kill */
|
|
|
|
#define CPU_KILL_ME (1)
|
|
|
|
/* The cpu couldn't die gracefully and is looping in the kernel */
|
|
|
|
#define CPU_STUCK_IN_KERNEL (2)
|
|
|
|
/* Fatal system error detected by secondary CPU, crash the system */
|
|
|
|
#define CPU_PANIC_KERNEL (3)
|
|
|
|
|
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
|
2012-03-05 11:49:30 +00:00
|
|
|
#include <linux/threads.h>
|
|
|
|
#include <linux/cpumask.h>
|
|
|
|
#include <linux/thread_info.h>
|
|
|
|
|
|
|
|
#define raw_smp_processor_id() (current_thread_info()->cpu)
|
|
|
|
|
|
|
|
struct seq_file;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* generate IPI list text
|
|
|
|
*/
|
|
|
|
extern void show_ipi_list(struct seq_file *p, int prec);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Called from C code, this handles an IPI.
|
|
|
|
*/
|
|
|
|
extern void handle_IPI(int ipinr, struct pt_regs *regs);
|
|
|
|
|
|
|
|
/*
|
2015-03-24 14:02:45 +00:00
|
|
|
* Discover the set of possible CPUs and determine their
|
|
|
|
* SMP operations.
|
2012-03-05 11:49:30 +00:00
|
|
|
*/
|
2015-05-13 13:12:47 +00:00
|
|
|
extern void smp_init_cpus(void);
|
2012-03-05 11:49:30 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Provide a function to raise an IPI cross call on CPUs in callmap.
|
|
|
|
*/
|
|
|
|
extern void set_smp_cross_call(void (*)(const struct cpumask *, unsigned int));
|
|
|
|
|
2014-08-16 16:48:05 +00:00
|
|
|
extern void (*__smp_cross_call)(const struct cpumask *, unsigned int);
|
|
|
|
|
2012-03-05 11:49:30 +00:00
|
|
|
/*
|
|
|
|
* Called from the secondary holding pen, this is the secondary CPU entry point.
|
|
|
|
*/
|
|
|
|
asmlinkage void secondary_start_kernel(void);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Initial data for bringing up a secondary CPU.
|
2016-02-23 10:31:42 +00:00
|
|
|
* @stack - sp for the secondary CPU
|
|
|
|
* @status - Result passed back from the secondary CPU to
|
|
|
|
* indicate failure.
|
2012-03-05 11:49:30 +00:00
|
|
|
*/
|
|
|
|
struct secondary_data {
|
|
|
|
void *stack;
|
2016-02-23 10:31:42 +00:00
|
|
|
long status;
|
2012-03-05 11:49:30 +00:00
|
|
|
};
|
2016-02-23 10:31:42 +00:00
|
|
|
|
2012-03-05 11:49:30 +00:00
|
|
|
extern struct secondary_data secondary_data;
|
2016-02-23 10:31:42 +00:00
|
|
|
extern long __early_cpu_boot_status;
|
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
|
|
|
extern void secondary_entry(void);
|
2012-03-05 11:49:30 +00:00
|
|
|
|
|
|
|
extern void arch_send_call_function_single_ipi(int cpu);
|
|
|
|
extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
|
|
|
|
|
2016-01-26 11:10:38 +00:00
|
|
|
#ifdef CONFIG_ARM64_ACPI_PARKING_PROTOCOL
|
|
|
|
extern void arch_send_wakeup_ipi_mask(const struct cpumask *mask);
|
|
|
|
#else
|
|
|
|
static inline void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
|
|
|
|
{
|
|
|
|
BUILD_BUG();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-10-24 19:30:18 +00:00
|
|
|
extern int __cpu_disable(void);
|
|
|
|
|
|
|
|
extern void __cpu_die(unsigned int cpu);
|
|
|
|
extern void cpu_die(void);
|
2016-02-23 10:31:41 +00:00
|
|
|
extern void cpu_die_early(void);
|
2013-10-24 19:30:18 +00:00
|
|
|
|
2016-02-23 10:31:39 +00:00
|
|
|
static inline void cpu_park_loop(void)
|
|
|
|
{
|
|
|
|
for (;;) {
|
|
|
|
wfe();
|
|
|
|
wfi();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-23 10:31:42 +00:00
|
|
|
static inline void update_cpu_boot_status(int val)
|
|
|
|
{
|
|
|
|
WRITE_ONCE(secondary_data.status, val);
|
|
|
|
/* Ensure the visibility of the status update */
|
|
|
|
dsb(ishst);
|
|
|
|
}
|
|
|
|
|
2016-04-12 14:46:00 +00:00
|
|
|
/*
|
|
|
|
* The calling secondary CPU has detected serious configuration mismatch,
|
|
|
|
* which calls for a kernel panic. Update the boot status and park the calling
|
|
|
|
* CPU.
|
|
|
|
*/
|
|
|
|
static inline void cpu_panic_kernel(void)
|
|
|
|
{
|
|
|
|
update_cpu_boot_status(CPU_PANIC_KERNEL);
|
|
|
|
cpu_park_loop();
|
|
|
|
}
|
|
|
|
|
2016-02-23 10:31:42 +00:00
|
|
|
#endif /* ifndef __ASSEMBLY__ */
|
|
|
|
|
2012-03-05 11:49:30 +00:00
|
|
|
#endif /* ifndef __ASM_SMP_H */
|