diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2016-07-05 07:03:49 +0200 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2016-07-21 10:56:31 +0200 |
commit | d3cbff1b5a90afe6cb201aa2187c9609e21f92ad (patch) | |
tree | f0ced407effcad48705b598ed5618c222d82983a /arch/powerpc/kernel/setup_64.c | |
parent | powerpc: Move FW feature probing out of pseries probe() (diff) | |
download | linux-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.c | 56 |
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(); |