summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/setup_64.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2016-07-05 07:03:49 +0200
committerMichael Ellerman <mpe@ellerman.id.au>2016-07-21 10:56:31 +0200
commitd3cbff1b5a90afe6cb201aa2187c9609e21f92ad (patch)
treef0ced407effcad48705b598ed5618c222d82983a /arch/powerpc/kernel/setup_64.c
parentpowerpc: Move FW feature probing out of pseries probe() (diff)
downloadlinux-d3cbff1b5a90afe6cb201aa2187c9609e21f92ad.tar.xz
linux-d3cbff1b5a90afe6cb201aa2187c9609e21f92ad.zip
powerpc: Put exception configuration in a common place
The various calls to establish exception endianness and AIL are now done from a single point using already established CPU and FW feature bits to decide what to do. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/kernel/setup_64.c')
-rw-r--r--arch/powerpc/kernel/setup_64.c56
1 files changed, 42 insertions, 14 deletions
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 155dbcce8ef8..4ffd090633de 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -69,6 +69,7 @@
#include <asm/kvm_ppc.h>
#include <asm/hugetlb.h>
#include <asm/livepatch.h>
+#include <asm/opal.h>
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
@@ -205,23 +206,50 @@ static void fixup_boot_paca(void)
get_paca()->data_offset = 0;
}
-static void cpu_ready_for_interrupts(void)
+static void configure_exceptions(void)
{
- /* Set IR and DR in PACA MSR */
- get_paca()->kernel_msr = MSR_KERNEL;
-
/*
- * Enable AIL if supported, and we are in hypervisor mode. If we are
- * not in hypervisor mode, we enable relocation-on interrupts later
- * in pSeries_setup_arch() using the H_SET_MODE hcall.
+ * Setup the trampolines from the lowmem exception vectors
+ * to the kdump kernel when not using a relocatable kernel.
*/
- if (cpu_has_feature(CPU_FTR_HVMODE) &&
- cpu_has_feature(CPU_FTR_ARCH_207S)) {
- unsigned long lpcr = mfspr(SPRN_LPCR);
- mtspr(SPRN_LPCR, lpcr | LPCR_AIL_3);
+ setup_kdump_trampoline();
+
+ /* Under a PAPR hypervisor, we need hypercalls */
+ if (firmware_has_feature(FW_FEATURE_SET_MODE)) {
+ /* Enable AIL if possible */
+ pseries_enable_reloc_on_exc();
+
+ /*
+ * Tell the hypervisor that we want our exceptions to
+ * be taken in little endian mode.
+ *
+ * We don't call this for big endian as our calling convention
+ * makes us always enter in BE, and the call may fail under
+ * some circumstances with kdump.
+ */
+#ifdef __LITTLE_ENDIAN__
+ pseries_little_endian_exceptions();
+#endif
+ } else {
+ /* Set endian mode using OPAL */
+ if (firmware_has_feature(FW_FEATURE_OPAL))
+ opal_configure_cores();
+
+ /* Enable AIL if supported, and we are in hypervisor mode */
+ if (cpu_has_feature(CPU_FTR_HVMODE) &&
+ cpu_has_feature(CPU_FTR_ARCH_207S)) {
+ unsigned long lpcr = mfspr(SPRN_LPCR);
+ mtspr(SPRN_LPCR, lpcr | LPCR_AIL_3);
+ }
}
}
+static void cpu_ready_for_interrupts(void)
+{
+ /* Set IR and DR in PACA MSR */
+ get_paca()->kernel_msr = MSR_KERNEL;
+}
+
/*
* Early initialization entry point. This is called by head.S
* with MMU translation disabled. We rely on the "feature" of
@@ -277,10 +305,10 @@ void __init early_setup(unsigned long dt_ptr)
probe_machine();
/*
- * Setup the trampolines from the lowmem exception vectors
- * to the kdump kernel when not using a relocatable kernel.
+ * Configure exception handlers. This include setting up trampolines
+ * if needed, setting exception endian mode, etc...
*/
- setup_kdump_trampoline();
+ configure_exceptions();
/* Initialize the hash table or TLB handling */
early_init_mmu();