Merge branch 'for-linus' of git://ftp.arm.linux.org.uk/~rmk/linux-arm
Pull ARM updates from Russell King: - UEFI boot and runtime services support for ARM from Ard Biesheuvel and Roy Franz. - DT compatibility with old atags booting protocol for Nokia N900 devices from Ivaylo Dimitrov. - PSCI firmware interface using new arm-smc calling convention from Jens Wiklander. - Runtime patching for udiv/sdiv instructions for ARMv7 CPUs that support these instructions from Nicolas Pitre. - L2x0 cache updates from Dirk B and Linus Walleij. - Randconfig fixes from Arnd Bergmann. - ARMv7M (nommu) updates from Ezequiel Garcia * 'for-linus' of git://ftp.arm.linux.org.uk/~rmk/linux-arm: (34 commits) ARM: 8481/2: drivers: psci: replace psci firmware calls ARM: 8480/2: arm64: add implementation for arm-smccc ARM: 8479/2: add implementation for arm-smccc ARM: 8478/2: arm/arm64: add arm-smccc ARM: 8494/1: mm: Enable PXN when running non-LPAE kernel on LPAE processor ARM: 8496/1: OMAP: RX51: save ATAGS data in the early boot stage ARM: 8495/1: ATAGS: move save_atags() to arch/arm/include/asm/setup.h ARM: 8452/3: PJ4: make coprocessor access sequences buildable in Thumb2 mode ARM: 8482/1: l2x0: make it possible to disable outer sync from DT ARM: 8488/1: Make IPI_CPU_BACKTRACE a "non-secure" SGI ARM: 8487/1: Remove IPI_CALL_FUNC_SINGLE ARM: 8485/1: cpuidle: remove cpu parameter from the cpuidle_ops suspend hook ARM: 8484/1: Documentation: l2c2x0: Mention separate controllers explicitly ARM: 8483/1: Documentation: l2c: Rename l2cc to l2c2x0 ARM: 8477/1: runtime patch udiv/sdiv instructions into __aeabi_{u}idiv() ARM: 8476/1: VDSO: use PTR_ERR_OR_ZERO for vma check ARM: 8453/2: proc-v7.S: don't locate temporary stack space in .text section ARM: add UEFI stub support ARM: wire up UEFI init and runtime support ARM: only consider memblocks with NOMAP cleared for linear mapping ...
This commit is contained in:
@@ -73,10 +73,10 @@ obj-$(CONFIG_IWMMXT) += iwmmxt.o
|
||||
obj-$(CONFIG_PERF_EVENTS) += perf_regs.o perf_callchain.o
|
||||
obj-$(CONFIG_HW_PERF_EVENTS) += perf_event_xscale.o perf_event_v6.o \
|
||||
perf_event_v7.o
|
||||
CFLAGS_pj4-cp0.o := -marm
|
||||
AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
|
||||
obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o
|
||||
obj-$(CONFIG_VDSO) += vdso.o
|
||||
obj-$(CONFIG_EFI) += efi.o
|
||||
|
||||
ifneq ($(CONFIG_ARCH_EBSA110),y)
|
||||
obj-y += io.o
|
||||
@@ -88,8 +88,9 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
|
||||
|
||||
obj-$(CONFIG_ARM_VIRT_EXT) += hyp-stub.o
|
||||
ifeq ($(CONFIG_ARM_PSCI),y)
|
||||
obj-y += psci-call.o
|
||||
obj-$(CONFIG_SMP) += psci_smp.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_HAVE_ARM_SMCCC) += smccc-call.o
|
||||
|
||||
extra-y := $(head-y) vmlinux.lds
|
||||
|
@@ -16,6 +16,7 @@
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/arm-smccc.h>
|
||||
|
||||
#include <asm/checksum.h>
|
||||
#include <asm/ftrace.h>
|
||||
@@ -175,3 +176,8 @@ EXPORT_SYMBOL(__gnu_mcount_nc);
|
||||
EXPORT_SYMBOL(__pv_phys_pfn_offset);
|
||||
EXPORT_SYMBOL(__pv_offset);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HAVE_ARM_SMCCC
|
||||
EXPORT_SYMBOL(arm_smccc_smc);
|
||||
EXPORT_SYMBOL(arm_smccc_hvc);
|
||||
#endif
|
||||
|
@@ -1,9 +1,3 @@
|
||||
#ifdef CONFIG_ATAGS_PROC
|
||||
extern void save_atags(struct tag *tags);
|
||||
#else
|
||||
static inline void save_atags(struct tag *tags) { }
|
||||
#endif
|
||||
|
||||
void convert_to_tag_list(struct tag *tags);
|
||||
|
||||
#ifdef CONFIG_ATAGS
|
||||
|
@@ -56,7 +56,7 @@ int arm_cpuidle_suspend(int index)
|
||||
int cpu = smp_processor_id();
|
||||
|
||||
if (cpuidle_ops[cpu].suspend)
|
||||
ret = cpuidle_ops[cpu].suspend(cpu, index);
|
||||
ret = cpuidle_ops[cpu].suspend(index);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
38
arch/arm/kernel/efi.c
Normal file
38
arch/arm/kernel/efi.c
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Linaro Ltd <ard.biesheuvel@linaro.org>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/efi.h>
|
||||
#include <asm/efi.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mmu_context.h>
|
||||
|
||||
int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md)
|
||||
{
|
||||
struct map_desc desc = {
|
||||
.virtual = md->virt_addr,
|
||||
.pfn = __phys_to_pfn(md->phys_addr),
|
||||
.length = md->num_pages * EFI_PAGE_SIZE,
|
||||
};
|
||||
|
||||
/*
|
||||
* Order is important here: memory regions may have all of the
|
||||
* bits below set (and usually do), so we check them in order of
|
||||
* preference.
|
||||
*/
|
||||
if (md->attribute & EFI_MEMORY_WB)
|
||||
desc.type = MT_MEMORY_RWX;
|
||||
else if (md->attribute & EFI_MEMORY_WT)
|
||||
desc.type = MT_MEMORY_RWX_NONCACHED;
|
||||
else if (md->attribute & EFI_MEMORY_WC)
|
||||
desc.type = MT_DEVICE_WC;
|
||||
else
|
||||
desc.type = MT_DEVICE;
|
||||
|
||||
create_mapping_late(mm, &desc, true);
|
||||
return 0;
|
||||
}
|
@@ -88,7 +88,7 @@ __pendsv_entry:
|
||||
@ execute the pending work, including reschedule
|
||||
get_thread_info tsk
|
||||
mov why, #0
|
||||
b ret_to_user
|
||||
b ret_to_user_from_irq
|
||||
ENDPROC(__pendsv_entry)
|
||||
|
||||
/*
|
||||
|
@@ -66,9 +66,13 @@ static void __init pj4_cp_access_write(u32 value)
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"mcr p15, 0, %1, c1, c0, 2\n\t"
|
||||
#ifdef CONFIG_THUMB2_KERNEL
|
||||
"isb\n\t"
|
||||
#else
|
||||
"mrc p15, 0, %0, c1, c0, 2\n\t"
|
||||
"mov %0, %0\n\t"
|
||||
"sub pc, pc, #4\n\t"
|
||||
#endif
|
||||
: "=r" (temp) : "r" (value));
|
||||
}
|
||||
|
||||
|
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 2015 ARM Limited
|
||||
*
|
||||
* Author: Mark Rutland <mark.rutland@arm.com>
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
|
||||
#include <asm/opcodes-sec.h>
|
||||
#include <asm/opcodes-virt.h>
|
||||
|
||||
/* int __invoke_psci_fn_hvc(u32 function_id, u32 arg0, u32 arg1, u32 arg2) */
|
||||
ENTRY(__invoke_psci_fn_hvc)
|
||||
__HVC(0)
|
||||
bx lr
|
||||
ENDPROC(__invoke_psci_fn_hvc)
|
||||
|
||||
/* int __invoke_psci_fn_smc(u32 function_id, u32 arg0, u32 arg1, u32 arg2) */
|
||||
ENTRY(__invoke_psci_fn_smc)
|
||||
__SMC(0)
|
||||
bx lr
|
||||
ENDPROC(__invoke_psci_fn_smc)
|
@@ -7,6 +7,7 @@
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/efi.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/stddef.h>
|
||||
@@ -37,7 +38,9 @@
|
||||
#include <asm/cp15.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/cputype.h>
|
||||
#include <asm/efi.h>
|
||||
#include <asm/elf.h>
|
||||
#include <asm/early_ioremap.h>
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/procinfo.h>
|
||||
#include <asm/psci.h>
|
||||
@@ -375,6 +378,72 @@ void __init early_print(const char *str, ...)
|
||||
printk("%s", buf);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARM_PATCH_IDIV
|
||||
|
||||
static inline u32 __attribute_const__ sdiv_instruction(void)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
|
||||
/* "sdiv r0, r0, r1" */
|
||||
u32 insn = __opcode_thumb32_compose(0xfb90, 0xf0f1);
|
||||
return __opcode_to_mem_thumb32(insn);
|
||||
}
|
||||
|
||||
/* "sdiv r0, r0, r1" */
|
||||
return __opcode_to_mem_arm(0xe710f110);
|
||||
}
|
||||
|
||||
static inline u32 __attribute_const__ udiv_instruction(void)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
|
||||
/* "udiv r0, r0, r1" */
|
||||
u32 insn = __opcode_thumb32_compose(0xfbb0, 0xf0f1);
|
||||
return __opcode_to_mem_thumb32(insn);
|
||||
}
|
||||
|
||||
/* "udiv r0, r0, r1" */
|
||||
return __opcode_to_mem_arm(0xe730f110);
|
||||
}
|
||||
|
||||
static inline u32 __attribute_const__ bx_lr_instruction(void)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
|
||||
/* "bx lr; nop" */
|
||||
u32 insn = __opcode_thumb32_compose(0x4770, 0x46c0);
|
||||
return __opcode_to_mem_thumb32(insn);
|
||||
}
|
||||
|
||||
/* "bx lr" */
|
||||
return __opcode_to_mem_arm(0xe12fff1e);
|
||||
}
|
||||
|
||||
static void __init patch_aeabi_idiv(void)
|
||||
{
|
||||
extern void __aeabi_uidiv(void);
|
||||
extern void __aeabi_idiv(void);
|
||||
uintptr_t fn_addr;
|
||||
unsigned int mask;
|
||||
|
||||
mask = IS_ENABLED(CONFIG_THUMB2_KERNEL) ? HWCAP_IDIVT : HWCAP_IDIVA;
|
||||
if (!(elf_hwcap & mask))
|
||||
return;
|
||||
|
||||
pr_info("CPU: div instructions available: patching division code\n");
|
||||
|
||||
fn_addr = ((uintptr_t)&__aeabi_uidiv) & ~1;
|
||||
((u32 *)fn_addr)[0] = udiv_instruction();
|
||||
((u32 *)fn_addr)[1] = bx_lr_instruction();
|
||||
flush_icache_range(fn_addr, fn_addr + 8);
|
||||
|
||||
fn_addr = ((uintptr_t)&__aeabi_idiv) & ~1;
|
||||
((u32 *)fn_addr)[0] = sdiv_instruction();
|
||||
((u32 *)fn_addr)[1] = bx_lr_instruction();
|
||||
flush_icache_range(fn_addr, fn_addr + 8);
|
||||
}
|
||||
|
||||
#else
|
||||
static inline void patch_aeabi_idiv(void) { }
|
||||
#endif
|
||||
|
||||
static void __init cpuid_init_hwcaps(void)
|
||||
{
|
||||
int block;
|
||||
@@ -642,6 +711,7 @@ static void __init setup_processor(void)
|
||||
elf_hwcap = list->elf_hwcap;
|
||||
|
||||
cpuid_init_hwcaps();
|
||||
patch_aeabi_idiv();
|
||||
|
||||
#ifndef CONFIG_ARM_THUMB
|
||||
elf_hwcap &= ~(HWCAP_THUMB | HWCAP_IDIVT);
|
||||
@@ -956,8 +1026,8 @@ void __init setup_arch(char **cmdline_p)
|
||||
strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
|
||||
*cmdline_p = cmd_line;
|
||||
|
||||
if (IS_ENABLED(CONFIG_FIX_EARLYCON_MEM))
|
||||
early_fixmap_init();
|
||||
early_fixmap_init();
|
||||
early_ioremap_init();
|
||||
|
||||
parse_early_param();
|
||||
|
||||
@@ -965,9 +1035,12 @@ void __init setup_arch(char **cmdline_p)
|
||||
early_paging_init(mdesc);
|
||||
#endif
|
||||
setup_dma_zone(mdesc);
|
||||
efi_init();
|
||||
sanity_check_meminfo();
|
||||
arm_memblock_init(mdesc);
|
||||
|
||||
early_ioremap_reset();
|
||||
|
||||
paging_init(mdesc);
|
||||
request_standard_resources(mdesc);
|
||||
|
||||
|
62
arch/arm/kernel/smccc-call.S
Normal file
62
arch/arm/kernel/smccc-call.S
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Linaro Limited
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#include <linux/linkage.h>
|
||||
|
||||
#include <asm/opcodes-sec.h>
|
||||
#include <asm/opcodes-virt.h>
|
||||
#include <asm/unwind.h>
|
||||
|
||||
/*
|
||||
* Wrap c macros in asm macros to delay expansion until after the
|
||||
* SMCCC asm macro is expanded.
|
||||
*/
|
||||
.macro SMCCC_SMC
|
||||
__SMC(0)
|
||||
.endm
|
||||
|
||||
.macro SMCCC_HVC
|
||||
__HVC(0)
|
||||
.endm
|
||||
|
||||
.macro SMCCC instr
|
||||
UNWIND( .fnstart)
|
||||
mov r12, sp
|
||||
push {r4-r7}
|
||||
UNWIND( .save {r4-r7})
|
||||
ldm r12, {r4-r7}
|
||||
\instr
|
||||
pop {r4-r7}
|
||||
ldr r12, [sp, #(4 * 4)]
|
||||
stm r12, {r0-r3}
|
||||
bx lr
|
||||
UNWIND( .fnend)
|
||||
.endm
|
||||
|
||||
/*
|
||||
* void smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2,
|
||||
* unsigned long a3, unsigned long a4, unsigned long a5,
|
||||
* unsigned long a6, unsigned long a7, struct arm_smccc_res *res)
|
||||
*/
|
||||
ENTRY(arm_smccc_smc)
|
||||
SMCCC SMCCC_SMC
|
||||
ENDPROC(arm_smccc_smc)
|
||||
|
||||
/*
|
||||
* void smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2,
|
||||
* unsigned long a3, unsigned long a4, unsigned long a5,
|
||||
* unsigned long a6, unsigned long a7, struct arm_smccc_res *res)
|
||||
*/
|
||||
ENTRY(arm_smccc_hvc)
|
||||
SMCCC SMCCC_HVC
|
||||
ENDPROC(arm_smccc_hvc)
|
@@ -69,11 +69,15 @@ enum ipi_msg_type {
|
||||
IPI_TIMER,
|
||||
IPI_RESCHEDULE,
|
||||
IPI_CALL_FUNC,
|
||||
IPI_CALL_FUNC_SINGLE,
|
||||
IPI_CPU_STOP,
|
||||
IPI_IRQ_WORK,
|
||||
IPI_COMPLETION,
|
||||
IPI_CPU_BACKTRACE = 15,
|
||||
IPI_CPU_BACKTRACE,
|
||||
/*
|
||||
* SGI8-15 can be reserved by secure firmware, and thus may
|
||||
* not be usable by the kernel. Please keep the above limited
|
||||
* to at most 8 entries.
|
||||
*/
|
||||
};
|
||||
|
||||
static DECLARE_COMPLETION(cpu_running);
|
||||
@@ -475,7 +479,6 @@ static const char *ipi_types[NR_IPI] __tracepoint_string = {
|
||||
S(IPI_TIMER, "Timer broadcast interrupts"),
|
||||
S(IPI_RESCHEDULE, "Rescheduling interrupts"),
|
||||
S(IPI_CALL_FUNC, "Function call interrupts"),
|
||||
S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"),
|
||||
S(IPI_CPU_STOP, "CPU stop interrupts"),
|
||||
S(IPI_IRQ_WORK, "IRQ work interrupts"),
|
||||
S(IPI_COMPLETION, "completion interrupts"),
|
||||
@@ -525,7 +528,7 @@ void arch_send_wakeup_ipi_mask(const struct cpumask *mask)
|
||||
|
||||
void arch_send_call_function_single_ipi(int cpu)
|
||||
{
|
||||
smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
|
||||
smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IRQ_WORK
|
||||
@@ -620,12 +623,6 @@ void handle_IPI(int ipinr, struct pt_regs *regs)
|
||||
irq_exit();
|
||||
break;
|
||||
|
||||
case IPI_CALL_FUNC_SINGLE:
|
||||
irq_enter();
|
||||
generic_smp_call_function_single_interrupt();
|
||||
irq_exit();
|
||||
break;
|
||||
|
||||
case IPI_CPU_STOP:
|
||||
irq_enter();
|
||||
ipi_cpu_stop(cpu);
|
||||
|
@@ -224,7 +224,7 @@ static int install_vvar(struct mm_struct *mm, unsigned long addr)
|
||||
VM_READ | VM_MAYREAD,
|
||||
&vdso_data_mapping);
|
||||
|
||||
return IS_ERR(vma) ? PTR_ERR(vma) : 0;
|
||||
return PTR_ERR_OR_ZERO(vma);
|
||||
}
|
||||
|
||||
/* assumes mmap_sem is write-locked */
|
||||
|
Reference in New Issue
Block a user