2013-10-24 19:30:15 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2013 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_CPU_OPS_H
|
|
|
|
#define __ASM_CPU_OPS_H
|
|
|
|
|
|
|
|
#include <linux/init.h>
|
|
|
|
#include <linux/threads.h>
|
|
|
|
|
|
|
|
struct device_node;
|
|
|
|
|
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
|
|
|
/**
|
|
|
|
* struct cpu_operations - Callback operations for hotplugging CPUs.
|
|
|
|
*
|
|
|
|
* @name: Name of the property as appears in a devicetree cpu node's
|
|
|
|
* enable-method property.
|
|
|
|
* @cpu_init: Reads any data necessary for a specific enable-method from the
|
|
|
|
* devicetree, for a given cpu node and proposed logical id.
|
|
|
|
* @cpu_prepare: Early one-time preparation step for a cpu. If there is a
|
|
|
|
* mechanism for doing so, tests whether it is possible to boot
|
|
|
|
* the given CPU.
|
|
|
|
* @cpu_boot: Boots a cpu into the kernel.
|
|
|
|
* @cpu_postboot: Optionally, perform any post-boot cleanup or necesary
|
|
|
|
* synchronisation. Called from the cpu being booted.
|
2013-10-24 19:30:18 +00:00
|
|
|
* @cpu_disable: Prepares a cpu to die. May fail for some mechanism-specific
|
|
|
|
* reason, which will cause the hot unplug to be aborted. Called
|
|
|
|
* from the cpu to be killed.
|
|
|
|
* @cpu_die: Makes a cpu leave the kernel. Must not fail. Called from the
|
|
|
|
* cpu being killed.
|
2014-05-07 14:18:36 +00:00
|
|
|
* @cpu_kill: Ensures a cpu has left the kernel. Called from another cpu.
|
2015-01-26 18:33:44 +00:00
|
|
|
* @cpu_init_idle: Reads any data necessary to initialize CPU idle states from
|
|
|
|
* devicetree, for a given cpu node and proposed logical id.
|
arm64: kernel: cpu_{suspend/resume} implementation
Kernel subsystems like CPU idle and suspend to RAM require a generic
mechanism to suspend a processor, save its context and put it into
a quiescent state. The cpu_{suspend}/{resume} implementation provides
such a framework through a kernel interface allowing to save/restore
registers, flush the context to DRAM and suspend/resume to/from
low-power states where processor context may be lost.
The CPU suspend implementation relies on the suspend protocol registered
in CPU operations to carry out a suspend request after context is
saved and flushed to DRAM. The cpu_suspend interface:
int cpu_suspend(unsigned long arg);
allows to pass an opaque parameter that is handed over to the suspend CPU
operations back-end so that it can take action according to the
semantics attached to it. The arg parameter allows suspend to RAM and CPU
idle drivers to communicate to suspend protocol back-ends; it requires
standardization so that the interface can be reused seamlessly across
systems, paving the way for generic drivers.
Context memory is allocated on the stack, whose address is stashed in a
per-cpu variable to keep track of it and passed to core functions that
save/restore the registers required by the architecture.
Even though, upon successful execution, the cpu_suspend function shuts
down the suspending processor, the warm boot resume mechanism, based
on the cpu_resume function, makes the resume path operate as a
cpu_suspend function return, so that cpu_suspend can be treated as a C
function by the caller, which simplifies coding the PM drivers that rely
on the cpu_suspend API.
Upon context save, the minimal amount of memory is flushed to DRAM so
that it can be retrieved when the MMU is off and caches are not searched.
The suspend CPU operation, depending on the required operations (eg CPU vs
Cluster shutdown) is in charge of flushing the cache hierarchy either
implicitly (by calling firmware implementations like PSCI) or explicitly
by executing the required cache maintainance functions.
Debug exceptions are disabled during cpu_{suspend}/{resume} operations
so that debug registers can be saved and restored properly preventing
preemption from debug agents enabled in the kernel.
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
2013-07-22 11:22:13 +00:00
|
|
|
* @cpu_suspend: Suspends a cpu and saves the required context. May fail owing
|
|
|
|
* to wrong parameters or error conditions. Called from the
|
|
|
|
* CPU being suspended. Must be called with IRQs disabled.
|
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
|
|
|
struct cpu_operations {
|
|
|
|
const char *name;
|
|
|
|
int (*cpu_init)(struct device_node *, unsigned int);
|
|
|
|
int (*cpu_prepare)(unsigned int);
|
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
|
|
|
int (*cpu_boot)(unsigned int);
|
|
|
|
void (*cpu_postboot)(void);
|
2013-10-24 19:30:18 +00:00
|
|
|
#ifdef CONFIG_HOTPLUG_CPU
|
|
|
|
int (*cpu_disable)(unsigned int cpu);
|
|
|
|
void (*cpu_die)(unsigned int cpu);
|
2014-05-07 14:18:36 +00:00
|
|
|
int (*cpu_kill)(unsigned int cpu);
|
2013-10-24 19:30:18 +00:00
|
|
|
#endif
|
2015-01-26 18:33:44 +00:00
|
|
|
#ifdef CONFIG_CPU_IDLE
|
|
|
|
int (*cpu_init_idle)(struct device_node *, unsigned int);
|
arm64: kernel: cpu_{suspend/resume} implementation
Kernel subsystems like CPU idle and suspend to RAM require a generic
mechanism to suspend a processor, save its context and put it into
a quiescent state. The cpu_{suspend}/{resume} implementation provides
such a framework through a kernel interface allowing to save/restore
registers, flush the context to DRAM and suspend/resume to/from
low-power states where processor context may be lost.
The CPU suspend implementation relies on the suspend protocol registered
in CPU operations to carry out a suspend request after context is
saved and flushed to DRAM. The cpu_suspend interface:
int cpu_suspend(unsigned long arg);
allows to pass an opaque parameter that is handed over to the suspend CPU
operations back-end so that it can take action according to the
semantics attached to it. The arg parameter allows suspend to RAM and CPU
idle drivers to communicate to suspend protocol back-ends; it requires
standardization so that the interface can be reused seamlessly across
systems, paving the way for generic drivers.
Context memory is allocated on the stack, whose address is stashed in a
per-cpu variable to keep track of it and passed to core functions that
save/restore the registers required by the architecture.
Even though, upon successful execution, the cpu_suspend function shuts
down the suspending processor, the warm boot resume mechanism, based
on the cpu_resume function, makes the resume path operate as a
cpu_suspend function return, so that cpu_suspend can be treated as a C
function by the caller, which simplifies coding the PM drivers that rely
on the cpu_suspend API.
Upon context save, the minimal amount of memory is flushed to DRAM so
that it can be retrieved when the MMU is off and caches are not searched.
The suspend CPU operation, depending on the required operations (eg CPU vs
Cluster shutdown) is in charge of flushing the cache hierarchy either
implicitly (by calling firmware implementations like PSCI) or explicitly
by executing the required cache maintainance functions.
Debug exceptions are disabled during cpu_{suspend}/{resume} operations
so that debug registers can be saved and restored properly preventing
preemption from debug agents enabled in the kernel.
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
2013-07-22 11:22:13 +00:00
|
|
|
int (*cpu_suspend)(unsigned long);
|
|
|
|
#endif
|
2013-10-24 19:30:15 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
extern const struct cpu_operations *cpu_ops[NR_CPUS];
|
2014-08-22 19:49:16 +00:00
|
|
|
int __init cpu_read_ops(struct device_node *dn, int cpu);
|
|
|
|
void __init cpu_read_bootcpu_ops(void);
|
2013-10-24 19:30:15 +00:00
|
|
|
|
|
|
|
#endif /* ifndef __ASM_CPU_OPS_H */
|