mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
Merge branch 'for-linus' of git://git.linaro.org/people/rmk/linux-arm
Pull more ARM updates from Russell King. This got a fair number of conflicts with the <asm/system.h> split, but also with some other sparse-irq and header file include cleanups. They all looked pretty trivial, though. * 'for-linus' of git://git.linaro.org/people/rmk/linux-arm: (59 commits) ARM: fix Kconfig warning for HAVE_BPF_JIT ARM: 7361/1: provide XIP_VIRT_ADDR for no-MMU builds ARM: 7349/1: integrator: convert to sparse irqs ARM: 7259/3: net: JIT compiler for packet filters ARM: 7334/1: add jump label support ARM: 7333/2: jump label: detect %c support for ARM ARM: 7338/1: add support for early console output via semihosting ARM: use set_current_blocked() and block_sigmask() ARM: exec: remove redundant set_fs(USER_DS) ARM: 7332/1: extract out code patch function from kprobes ARM: 7331/1: extract out insn generation code from ftrace ARM: 7330/1: ftrace: use canonical Thumb-2 wide instruction format ARM: 7351/1: ftrace: remove useless memory checks ARM: 7316/1: kexec: EOI active and mask all interrupts in kexec crash path ARM: Versatile Express: add NO_IOPORT ARM: get rid of asm/irq.h in asm/prom.h ARM: 7319/1: Print debug info for SIGBUS in user faults ARM: 7318/1: gic: refactor irq_start assignment ARM: 7317/1: irq: avoid NULL check in for_each_irq_desc loop ARM: 7315/1: perf: add support for the Cortex-A7 PMU ...
This commit is contained in:
commit
12679a2d7e
159 changed files with 2236 additions and 534 deletions
|
@ -9,6 +9,7 @@ config ARM
|
|||
select SYS_SUPPORTS_APM_EMULATION
|
||||
select GENERIC_ATOMIC64 if (CPU_V6 || !CPU_32v6K || !AEABI)
|
||||
select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
|
||||
select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
|
||||
select HAVE_ARCH_KGDB
|
||||
select HAVE_KPROBES if !XIP_KERNEL
|
||||
select HAVE_KRETPROBES if (HAVE_KPROBES)
|
||||
|
@ -21,6 +22,7 @@ config ARM
|
|||
select HAVE_KERNEL_GZIP
|
||||
select HAVE_KERNEL_LZO
|
||||
select HAVE_KERNEL_LZMA
|
||||
select HAVE_KERNEL_XZ
|
||||
select HAVE_IRQ_WORK
|
||||
select HAVE_PERF_EVENTS
|
||||
select PERF_USE_VMALLOC
|
||||
|
@ -28,10 +30,10 @@ config ARM
|
|||
select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7))
|
||||
select HAVE_C_RECORDMCOUNT
|
||||
select HAVE_GENERIC_HARDIRQS
|
||||
select HAVE_SPARSE_IRQ
|
||||
select GENERIC_IRQ_SHOW
|
||||
select CPU_PM if (SUSPEND || CPU_IDLE)
|
||||
select GENERIC_PCI_IOMAP
|
||||
select HAVE_BPF_JIT if NET
|
||||
help
|
||||
The ARM series is a line of low-power-consumption RISC chip designs
|
||||
licensed by ARM Ltd and targeted at embedded applications and
|
||||
|
@ -52,9 +54,6 @@ config MIGHT_HAVE_PCI
|
|||
config SYS_SUPPORTS_APM_EMULATION
|
||||
bool
|
||||
|
||||
config HAVE_SCHED_CLOCK
|
||||
bool
|
||||
|
||||
config GENERIC_GPIO
|
||||
bool
|
||||
|
||||
|
@ -269,6 +268,7 @@ config ARCH_INTEGRATOR
|
|||
select PLAT_VERSATILE
|
||||
select PLAT_VERSATILE_FPGA_IRQ
|
||||
select NEED_MACH_MEMORY_H
|
||||
select SPARSE_IRQ
|
||||
help
|
||||
Support for ARM's Integrator platform.
|
||||
|
||||
|
@ -315,6 +315,7 @@ config ARCH_VEXPRESS
|
|||
select HAVE_CLK
|
||||
select HAVE_PATA_PLATFORM
|
||||
select ICST
|
||||
select NO_IOPORT
|
||||
select PLAT_VERSATILE
|
||||
select PLAT_VERSATILE_CLCD
|
||||
help
|
||||
|
@ -354,6 +355,7 @@ config ARCH_HIGHBANK
|
|||
select GENERIC_CLOCKEVENTS
|
||||
select HAVE_ARM_SCU
|
||||
select HAVE_SMP
|
||||
select SPARSE_IRQ
|
||||
select USE_OF
|
||||
help
|
||||
Support for the Calxeda Highbank SoC based boards.
|
||||
|
@ -442,7 +444,6 @@ config ARCH_MXC
|
|||
select CLKDEV_LOOKUP
|
||||
select CLKSRC_MMIO
|
||||
select GENERIC_IRQ_CHIP
|
||||
select HAVE_SCHED_CLOCK
|
||||
select MULTI_IRQ_HANDLER
|
||||
help
|
||||
Support for Freescale MXC/iMX-based family of processors
|
||||
|
@ -537,7 +538,6 @@ config ARCH_IXP4XX
|
|||
select CPU_XSCALE
|
||||
select GENERIC_GPIO
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select HAVE_SCHED_CLOCK
|
||||
select MIGHT_HAVE_PCI
|
||||
select DMABOUNCE if PCI
|
||||
help
|
||||
|
@ -608,7 +608,6 @@ config ARCH_MMP
|
|||
select CLKDEV_LOOKUP
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select GPIO_PXA
|
||||
select HAVE_SCHED_CLOCK
|
||||
select TICK_ONESHOT
|
||||
select PLAT_PXA
|
||||
select SPARSE_IRQ
|
||||
|
@ -649,7 +648,6 @@ config ARCH_TEGRA
|
|||
select GENERIC_CLOCKEVENTS
|
||||
select GENERIC_GPIO
|
||||
select HAVE_CLK
|
||||
select HAVE_SCHED_CLOCK
|
||||
select HAVE_SMP
|
||||
select MIGHT_HAVE_CACHE_L2X0
|
||||
select ARCH_HAS_CPUFREQ
|
||||
|
@ -666,7 +664,6 @@ config ARCH_PICOXCELL
|
|||
select DW_APB_TIMER
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select GENERIC_GPIO
|
||||
select HAVE_SCHED_CLOCK
|
||||
select HAVE_TCM
|
||||
select NO_IOPORT
|
||||
select SPARSE_IRQ
|
||||
|
@ -694,7 +691,6 @@ config ARCH_PXA
|
|||
select ARCH_REQUIRE_GPIOLIB
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select GPIO_PXA
|
||||
select HAVE_SCHED_CLOCK
|
||||
select TICK_ONESHOT
|
||||
select PLAT_PXA
|
||||
select SPARSE_IRQ
|
||||
|
@ -761,7 +757,6 @@ config ARCH_SA1100
|
|||
select CPU_FREQ
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select CLKDEV_LOOKUP
|
||||
select HAVE_SCHED_CLOCK
|
||||
select TICK_ONESHOT
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
select HAVE_IDE
|
||||
|
@ -818,7 +813,6 @@ config ARCH_S5P64X0
|
|||
select CLKSRC_MMIO
|
||||
select HAVE_S3C2410_WATCHDOG if WATCHDOG
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select HAVE_SCHED_CLOCK
|
||||
select HAVE_S3C2410_I2C if I2C
|
||||
select HAVE_S3C_RTC if RTC_CLASS
|
||||
help
|
||||
|
@ -849,7 +843,6 @@ config ARCH_S5PV210
|
|||
select CLKSRC_MMIO
|
||||
select ARCH_HAS_CPUFREQ
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select HAVE_SCHED_CLOCK
|
||||
select HAVE_S3C2410_I2C if I2C
|
||||
select HAVE_S3C_RTC if RTC_CLASS
|
||||
select HAVE_S3C2410_WATCHDOG if WATCHDOG
|
||||
|
@ -892,7 +885,6 @@ config ARCH_U300
|
|||
depends on MMU
|
||||
select CLKSRC_MMIO
|
||||
select CPU_ARM926T
|
||||
select HAVE_SCHED_CLOCK
|
||||
select HAVE_TCM
|
||||
select ARM_AMBA
|
||||
select ARM_PATCH_PHYS_VIRT
|
||||
|
@ -951,7 +943,6 @@ config ARCH_OMAP
|
|||
select ARCH_HAS_CPUFREQ
|
||||
select CLKSRC_MMIO
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select HAVE_SCHED_CLOCK
|
||||
select ARCH_HAS_HOLES_MEMORYMODEL
|
||||
help
|
||||
Support for TI's OMAP platform (OMAP1/2/3/4).
|
||||
|
@ -1115,13 +1106,11 @@ config ARCH_ACORN
|
|||
config PLAT_IOP
|
||||
bool
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select HAVE_SCHED_CLOCK
|
||||
|
||||
config PLAT_ORION
|
||||
bool
|
||||
select CLKSRC_MMIO
|
||||
select GENERIC_IRQ_CHIP
|
||||
select HAVE_SCHED_CLOCK
|
||||
|
||||
config PLAT_PXA
|
||||
bool
|
||||
|
|
|
@ -292,6 +292,22 @@ choice
|
|||
Note that the system will appear to hang during boot if there
|
||||
is nothing connected to read from the DCC.
|
||||
|
||||
config DEBUG_SEMIHOSTING
|
||||
bool "Kernel low-level debug output via semihosting I"
|
||||
help
|
||||
Semihosting enables code running on an ARM target to use
|
||||
the I/O facilities on a host debugger/emulator through a
|
||||
simple SVC calls. The host debugger or emulator must have
|
||||
semihosting enabled for the special svc call to be trapped
|
||||
otherwise the kernel will crash.
|
||||
|
||||
This is known to work with OpenOCD, as wellas
|
||||
ARM's Fast Models, or any other controlling environment
|
||||
that implements semihosting.
|
||||
|
||||
For more details about semihosting, please see
|
||||
chapter 8 of DUI0203I_rvct_developer_guide.pdf from ARM Ltd.
|
||||
|
||||
endchoice
|
||||
|
||||
config EARLY_PRINTK
|
||||
|
|
|
@ -253,6 +253,7 @@ core-$(CONFIG_VFP) += arch/arm/vfp/
|
|||
|
||||
# If we have a machine-specific directory, then include it in the build.
|
||||
core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
|
||||
core-y += arch/arm/net/
|
||||
core-y += $(machdirs) $(platdirs)
|
||||
|
||||
drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
|
||||
|
|
2
arch/arm/boot/compressed/.gitignore
vendored
2
arch/arm/boot/compressed/.gitignore
vendored
|
@ -1,8 +1,10 @@
|
|||
ashldi3.S
|
||||
font.c
|
||||
lib1funcs.S
|
||||
piggy.gzip
|
||||
piggy.lzo
|
||||
piggy.lzma
|
||||
piggy.xzkern
|
||||
vmlinux
|
||||
vmlinux.lds
|
||||
|
||||
|
|
|
@ -92,6 +92,7 @@ SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/
|
|||
suffix_$(CONFIG_KERNEL_GZIP) = gzip
|
||||
suffix_$(CONFIG_KERNEL_LZO) = lzo
|
||||
suffix_$(CONFIG_KERNEL_LZMA) = lzma
|
||||
suffix_$(CONFIG_KERNEL_XZ) = xzkern
|
||||
|
||||
# Borrowed libfdt files for the ATAG compatibility mode
|
||||
|
||||
|
@ -112,10 +113,12 @@ endif
|
|||
|
||||
targets := vmlinux vmlinux.lds \
|
||||
piggy.$(suffix_y) piggy.$(suffix_y).o \
|
||||
lib1funcs.o lib1funcs.S font.o font.c head.o misc.o $(OBJS)
|
||||
lib1funcs.o lib1funcs.S ashldi3.o ashldi3.S \
|
||||
font.o font.c head.o misc.o $(OBJS)
|
||||
|
||||
# Make sure files are removed during clean
|
||||
extra-y += piggy.gzip piggy.lzo piggy.lzma lib1funcs.S $(libfdt) $(libfdt_hdrs)
|
||||
extra-y += piggy.gzip piggy.lzo piggy.lzma piggy.xzkern \
|
||||
lib1funcs.S ashldi3.S $(libfdt) $(libfdt_hdrs)
|
||||
|
||||
ifeq ($(CONFIG_FUNCTION_TRACER),y)
|
||||
ORIG_CFLAGS := $(KBUILD_CFLAGS)
|
||||
|
@ -151,6 +154,12 @@ lib1funcs = $(obj)/lib1funcs.o
|
|||
$(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S
|
||||
$(call cmd,shipped)
|
||||
|
||||
# For __aeabi_llsl
|
||||
ashldi3 = $(obj)/ashldi3.o
|
||||
|
||||
$(obj)/ashldi3.S: $(srctree)/arch/$(SRCARCH)/lib/ashldi3.S
|
||||
$(call cmd,shipped)
|
||||
|
||||
# We need to prevent any GOTOFF relocs being used with references
|
||||
# to symbols in the .bss section since we cannot relocate them
|
||||
# independently from the rest at run time. This can be achieved by
|
||||
|
@ -172,7 +181,7 @@ if [ $(words $(ZRELADDR)) -gt 1 -a "$(CONFIG_AUTO_ZRELADDR)" = "" ]; then \
|
|||
fi
|
||||
|
||||
$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \
|
||||
$(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE
|
||||
$(addprefix $(obj)/, $(OBJS)) $(lib1funcs) $(ashldi3) FORCE
|
||||
@$(check_for_multiple_zreladdr)
|
||||
$(call if_changed,ld)
|
||||
@$(check_for_bad_syms)
|
||||
|
|
|
@ -44,6 +44,12 @@ extern void error(char *);
|
|||
#include "../../../../lib/decompress_unlzma.c"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KERNEL_XZ
|
||||
#define memmove memmove
|
||||
#define memcpy memcpy
|
||||
#include "../../../../lib/decompress_unxz.c"
|
||||
#endif
|
||||
|
||||
int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x))
|
||||
{
|
||||
return decompress(input, len, NULL, NULL, output, NULL, error);
|
||||
|
|
6
arch/arm/boot/compressed/piggy.xzkern.S
Normal file
6
arch/arm/boot/compressed/piggy.xzkern.S
Normal file
|
@ -0,0 +1,6 @@
|
|||
.section .piggydata,#alloc
|
||||
.globl input_data
|
||||
input_data:
|
||||
.incbin "arch/arm/boot/compressed/piggy.xzkern"
|
||||
.globl input_data_end
|
||||
input_data_end:
|
|
@ -686,13 +686,12 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
|
|||
* For primary GICs, skip over SGIs.
|
||||
* For secondary GICs, skip over PPIs, too.
|
||||
*/
|
||||
hwirq_base = 32;
|
||||
if (gic_nr == 0) {
|
||||
if ((irq_start & 31) > 0) {
|
||||
hwirq_base = 16;
|
||||
if (irq_start != -1)
|
||||
irq_start = (irq_start & ~31) + 16;
|
||||
}
|
||||
if (gic_nr == 0 && (irq_start & 31) > 0) {
|
||||
hwirq_base = 16;
|
||||
if (irq_start != -1)
|
||||
irq_start = (irq_start & ~31) + 16;
|
||||
} else {
|
||||
hwirq_base = 32;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -57,18 +57,24 @@ CONFIG_NETDEVICES=y
|
|||
CONFIG_NET_ETHERNET=y
|
||||
CONFIG_NET_PCI=y
|
||||
CONFIG_E100=y
|
||||
CONFIG_SMC91X=y
|
||||
# CONFIG_KEYBOARD_ATKBD is not set
|
||||
# CONFIG_SERIO_SERPORT is not set
|
||||
CONFIG_SERIAL_AMBA_PL010=y
|
||||
CONFIG_SERIAL_AMBA_PL010_CONSOLE=y
|
||||
CONFIG_FB=y
|
||||
CONFIG_FB_MODE_HELPERS=y
|
||||
CONFIG_FB_ARMCLCD=y
|
||||
CONFIG_FB_MATROX=y
|
||||
CONFIG_FB_MATROX_MILLENIUM=y
|
||||
CONFIG_FB_MATROX_MYSTIQUE=y
|
||||
# CONFIG_VGA_CONSOLE is not set
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_ARMMMCI=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_PL030=y
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_VFAT_FS=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_JFFS2_FS=y
|
||||
CONFIG_CRAMFS=y
|
||||
|
@ -78,5 +84,7 @@ CONFIG_ROOT_NFS=y
|
|||
CONFIG_NFSD=y
|
||||
CONFIG_NFSD_V3=y
|
||||
CONFIG_PARTITION_ADVANCED=y
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
|
|
|
@ -130,8 +130,4 @@ struct mm_struct;
|
|||
extern unsigned long arch_randomize_brk(struct mm_struct *mm);
|
||||
#define arch_randomize_brk arch_randomize_brk
|
||||
|
||||
extern int vectors_user_mapping(void);
|
||||
#define arch_setup_additional_pages(bprm, uses_interp) vectors_user_mapping()
|
||||
#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
|
||||
|
||||
#endif
|
||||
|
|
|
@ -103,11 +103,11 @@
|
|||
#define L2X0_ADDR_FILTER_EN 1
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask);
|
||||
extern void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask);
|
||||
#if defined(CONFIG_CACHE_L2X0) && defined(CONFIG_OF)
|
||||
extern int l2x0_of_init(__u32 aux_val, __u32 aux_mask);
|
||||
extern int l2x0_of_init(u32 aux_val, u32 aux_mask);
|
||||
#else
|
||||
static inline int l2x0_of_init(__u32 aux_val, __u32 aux_mask)
|
||||
static inline int l2x0_of_init(u32 aux_val, u32 aux_mask)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
|
||||
#ifndef __ASM_HARDWARE_IT8152_H
|
||||
#define __ASM_HARDWARE_IT8152_H
|
||||
|
||||
#include <mach/irqs.h>
|
||||
|
||||
extern void __iomem *it8152_base_address;
|
||||
|
||||
#define IT8152_IO_BASE (it8152_base_address + 0x03e00000)
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
#ifndef __ASM_ARM_IRQ_H
|
||||
#define __ASM_ARM_IRQ_H
|
||||
|
||||
#define NR_IRQS_LEGACY 16
|
||||
|
||||
#ifndef CONFIG_SPARSE_IRQ
|
||||
#include <mach/irqs.h>
|
||||
#else
|
||||
#define NR_IRQS NR_IRQS_LEGACY
|
||||
#endif
|
||||
|
||||
#ifndef irq_canonicalize
|
||||
#define irq_canonicalize(i) (i)
|
||||
#endif
|
||||
|
||||
#define NR_IRQS_LEGACY 16
|
||||
|
||||
/*
|
||||
* Use this value to indicate lack of interrupt
|
||||
* capability
|
||||
|
|
41
arch/arm/include/asm/jump_label.h
Normal file
41
arch/arm/include/asm/jump_label.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
#ifndef _ASM_ARM_JUMP_LABEL_H
|
||||
#define _ASM_ARM_JUMP_LABEL_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
#define JUMP_LABEL_NOP_SIZE 4
|
||||
|
||||
#ifdef CONFIG_THUMB2_KERNEL
|
||||
#define JUMP_LABEL_NOP "nop.w"
|
||||
#else
|
||||
#define JUMP_LABEL_NOP "nop"
|
||||
#endif
|
||||
|
||||
static __always_inline bool arch_static_branch(struct jump_label_key *key)
|
||||
{
|
||||
asm goto("1:\n\t"
|
||||
JUMP_LABEL_NOP "\n\t"
|
||||
".pushsection __jump_table, \"aw\"\n\t"
|
||||
".word 1b, %l[l_yes], %c0\n\t"
|
||||
".popsection\n\t"
|
||||
: : "i" (key) : : l_yes);
|
||||
|
||||
return false;
|
||||
l_yes:
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
typedef u32 jump_label_t;
|
||||
|
||||
struct jump_entry {
|
||||
jump_label_t code;
|
||||
jump_label_t target;
|
||||
jump_label_t key;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -5,7 +5,9 @@
|
|||
#define _ASM_MC146818RTC_H
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#define RTC_IRQ BUILD_BUG_ON(1)
|
||||
|
||||
#ifndef RTC_PORT
|
||||
#define RTC_PORT(x) (0x70 + (x))
|
||||
|
|
|
@ -116,6 +116,8 @@
|
|||
#define MODULES_END (END_MEM)
|
||||
#define MODULES_VADDR (PHYS_OFFSET)
|
||||
|
||||
#define XIP_VIRT_ADDR(physaddr) (physaddr)
|
||||
|
||||
#endif /* !CONFIG_MMU */
|
||||
|
||||
/*
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <asm/cacheflush.h>
|
||||
#include <asm/cachetype.h>
|
||||
#include <asm/proc-fns.h>
|
||||
#include <asm-generic/mm_hooks.h>
|
||||
|
||||
void __check_kvm_seq(struct mm_struct *mm);
|
||||
|
||||
|
@ -133,32 +134,4 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
|||
#define deactivate_mm(tsk,mm) do { } while (0)
|
||||
#define activate_mm(prev,next) switch_mm(prev, next, NULL)
|
||||
|
||||
/*
|
||||
* We are inserting a "fake" vma for the user-accessible vector page so
|
||||
* gdb and friends can get to it through ptrace and /proc/<pid>/mem.
|
||||
* But we also want to remove it before the generic code gets to see it
|
||||
* during process exit or the unmapping of it would cause total havoc.
|
||||
* (the macro is used as remove_vma() is static to mm/mmap.c)
|
||||
*/
|
||||
#define arch_exit_mmap(mm) \
|
||||
do { \
|
||||
struct vm_area_struct *high_vma = find_vma(mm, 0xffff0000); \
|
||||
if (high_vma) { \
|
||||
BUG_ON(high_vma->vm_next); /* it should be last */ \
|
||||
if (high_vma->vm_prev) \
|
||||
high_vma->vm_prev->vm_next = NULL; \
|
||||
else \
|
||||
mm->mmap = NULL; \
|
||||
rb_erase(&high_vma->vm_rb, &mm->mm_rb); \
|
||||
mm->mmap_cache = NULL; \
|
||||
mm->map_count--; \
|
||||
remove_vma(high_vma); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static inline void arch_dup_mmap(struct mm_struct *oldmm,
|
||||
struct mm_struct *mm)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,4 +17,63 @@ extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr);
|
|||
#define ARM_OPCODE_CONDTEST_PASS 1
|
||||
#define ARM_OPCODE_CONDTEST_UNCOND 2
|
||||
|
||||
|
||||
/*
|
||||
* Opcode byteswap helpers
|
||||
*
|
||||
* These macros help with converting instructions between a canonical integer
|
||||
* format and in-memory representation, in an endianness-agnostic manner.
|
||||
*
|
||||
* __mem_to_opcode_*() convert from in-memory representation to canonical form.
|
||||
* __opcode_to_mem_*() convert from canonical form to in-memory representation.
|
||||
*
|
||||
*
|
||||
* Canonical instruction representation:
|
||||
*
|
||||
* ARM: 0xKKLLMMNN
|
||||
* Thumb 16-bit: 0x0000KKLL, where KK < 0xE8
|
||||
* Thumb 32-bit: 0xKKLLMMNN, where KK >= 0xE8
|
||||
*
|
||||
* There is no way to distinguish an ARM instruction in canonical representation
|
||||
* from a Thumb instruction (just as these cannot be distinguished in memory).
|
||||
* Where this distinction is important, it needs to be tracked separately.
|
||||
*
|
||||
* Note that values in the range 0x0000E800..0xE7FFFFFF intentionally do not
|
||||
* represent any valid Thumb-2 instruction. For this range,
|
||||
* __opcode_is_thumb32() and __opcode_is_thumb16() will both be false.
|
||||
*/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/swab.h>
|
||||
|
||||
#ifdef CONFIG_CPU_ENDIAN_BE8
|
||||
#define __opcode_to_mem_arm(x) swab32(x)
|
||||
#define __opcode_to_mem_thumb16(x) swab16(x)
|
||||
#define __opcode_to_mem_thumb32(x) swahb32(x)
|
||||
#else
|
||||
#define __opcode_to_mem_arm(x) ((u32)(x))
|
||||
#define __opcode_to_mem_thumb16(x) ((u16)(x))
|
||||
#define __opcode_to_mem_thumb32(x) swahw32(x)
|
||||
#endif
|
||||
|
||||
#define __mem_to_opcode_arm(x) __opcode_to_mem_arm(x)
|
||||
#define __mem_to_opcode_thumb16(x) __opcode_to_mem_thumb16(x)
|
||||
#define __mem_to_opcode_thumb32(x) __opcode_to_mem_thumb32(x)
|
||||
|
||||
/* Operations specific to Thumb opcodes */
|
||||
|
||||
/* Instruction size checks: */
|
||||
#define __opcode_is_thumb32(x) ((u32)(x) >= 0xE8000000UL)
|
||||
#define __opcode_is_thumb16(x) ((u32)(x) < 0xE800UL)
|
||||
|
||||
/* Operations to construct or split 32-bit Thumb instructions: */
|
||||
#define __opcode_thumb32_first(x) ((u16)((x) >> 16))
|
||||
#define __opcode_thumb32_second(x) ((u16)(x))
|
||||
#define __opcode_thumb32_compose(first, second) \
|
||||
(((u32)(u16)(first) << 16) | (u32)(u16)(second))
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* __ASM_ARM_OPCODES_H */
|
||||
|
|
|
@ -151,6 +151,8 @@ extern void __cpu_copy_user_highpage(struct page *to, struct page *from,
|
|||
#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
|
||||
extern void copy_page(void *to, const void *from);
|
||||
|
||||
#define __HAVE_ARCH_GATE_AREA 1
|
||||
|
||||
#ifdef CONFIG_ARM_LPAE
|
||||
#include <asm/pgtable-3level-types.h>
|
||||
#else
|
||||
|
|
|
@ -22,6 +22,7 @@ enum arm_perf_pmu_ids {
|
|||
ARM_PERF_PMU_ID_CA9,
|
||||
ARM_PERF_PMU_ID_CA5,
|
||||
ARM_PERF_PMU_ID_CA15,
|
||||
ARM_PERF_PMU_ID_CA7,
|
||||
ARM_NUM_PMU_IDS,
|
||||
};
|
||||
|
||||
|
|
|
@ -55,7 +55,6 @@ struct thread_struct {
|
|||
#define start_thread(regs,pc,sp) \
|
||||
({ \
|
||||
unsigned long *stack = (unsigned long *)sp; \
|
||||
set_fs(USER_DS); \
|
||||
memset(regs->uregs, 0, sizeof(regs->uregs)); \
|
||||
if (current->personality & ADDR_LIMIT_32BIT) \
|
||||
regs->ARM_cpsr = USR_MODE; \
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
|
||||
#ifdef CONFIG_OF
|
||||
|
||||
#include <asm/irq.h>
|
||||
|
||||
extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys);
|
||||
extern void arm_dt_memblock_reserve(void);
|
||||
|
||||
|
|
|
@ -318,6 +318,21 @@ extern struct cpu_tlb_fns cpu_tlb;
|
|||
|
||||
#define tlb_flag(f) ((always_tlb_flags & (f)) || (__tlb_flag & possible_tlb_flags & (f)))
|
||||
|
||||
#define __tlb_op(f, insnarg, arg) \
|
||||
do { \
|
||||
if (always_tlb_flags & (f)) \
|
||||
asm("mcr " insnarg \
|
||||
: : "r" (arg) : "cc"); \
|
||||
else if (possible_tlb_flags & (f)) \
|
||||
asm("tst %1, %2\n\t" \
|
||||
"mcrne " insnarg \
|
||||
: : "r" (arg), "r" (__tlb_flag), "Ir" (f) \
|
||||
: "cc"); \
|
||||
} while (0)
|
||||
|
||||
#define tlb_op(f, regs, arg) __tlb_op(f, "p15, 0, %0, " regs, arg)
|
||||
#define tlb_l2_op(f, regs, arg) __tlb_op(f, "p15, 1, %0, " regs, arg)
|
||||
|
||||
static inline void local_flush_tlb_all(void)
|
||||
{
|
||||
const int zero = 0;
|
||||
|
@ -326,16 +341,11 @@ static inline void local_flush_tlb_all(void)
|
|||
if (tlb_flag(TLB_WB))
|
||||
dsb();
|
||||
|
||||
if (tlb_flag(TLB_V3_FULL))
|
||||
asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc");
|
||||
if (tlb_flag(TLB_V4_U_FULL | TLB_V6_U_FULL))
|
||||
asm("mcr p15, 0, %0, c8, c7, 0" : : "r" (zero) : "cc");
|
||||
if (tlb_flag(TLB_V4_D_FULL | TLB_V6_D_FULL))
|
||||
asm("mcr p15, 0, %0, c8, c6, 0" : : "r" (zero) : "cc");
|
||||
if (tlb_flag(TLB_V4_I_FULL | TLB_V6_I_FULL))
|
||||
asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
|
||||
if (tlb_flag(TLB_V7_UIS_FULL))
|
||||
asm("mcr p15, 0, %0, c8, c3, 0" : : "r" (zero) : "cc");
|
||||
tlb_op(TLB_V3_FULL, "c6, c0, 0", zero);
|
||||
tlb_op(TLB_V4_U_FULL | TLB_V6_U_FULL, "c8, c7, 0", zero);
|
||||
tlb_op(TLB_V4_D_FULL | TLB_V6_D_FULL, "c8, c6, 0", zero);
|
||||
tlb_op(TLB_V4_I_FULL | TLB_V6_I_FULL, "c8, c5, 0", zero);
|
||||
tlb_op(TLB_V7_UIS_FULL, "c8, c3, 0", zero);
|
||||
|
||||
if (tlb_flag(TLB_BARRIER)) {
|
||||
dsb();
|
||||
|
@ -352,29 +362,23 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm)
|
|||
if (tlb_flag(TLB_WB))
|
||||
dsb();
|
||||
|
||||
if (cpumask_test_cpu(get_cpu(), mm_cpumask(mm))) {
|
||||
if (tlb_flag(TLB_V3_FULL))
|
||||
asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc");
|
||||
if (tlb_flag(TLB_V4_U_FULL))
|
||||
asm("mcr p15, 0, %0, c8, c7, 0" : : "r" (zero) : "cc");
|
||||
if (tlb_flag(TLB_V4_D_FULL))
|
||||
asm("mcr p15, 0, %0, c8, c6, 0" : : "r" (zero) : "cc");
|
||||
if (tlb_flag(TLB_V4_I_FULL))
|
||||
asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
|
||||
if (possible_tlb_flags & (TLB_V3_FULL|TLB_V4_U_FULL|TLB_V4_D_FULL|TLB_V4_I_FULL)) {
|
||||
if (cpumask_test_cpu(get_cpu(), mm_cpumask(mm))) {
|
||||
tlb_op(TLB_V3_FULL, "c6, c0, 0", zero);
|
||||
tlb_op(TLB_V4_U_FULL, "c8, c7, 0", zero);
|
||||
tlb_op(TLB_V4_D_FULL, "c8, c6, 0", zero);
|
||||
tlb_op(TLB_V4_I_FULL, "c8, c5, 0", zero);
|
||||
}
|
||||
put_cpu();
|
||||
}
|
||||
put_cpu();
|
||||
|
||||
if (tlb_flag(TLB_V6_U_ASID))
|
||||
asm("mcr p15, 0, %0, c8, c7, 2" : : "r" (asid) : "cc");
|
||||
if (tlb_flag(TLB_V6_D_ASID))
|
||||
asm("mcr p15, 0, %0, c8, c6, 2" : : "r" (asid) : "cc");
|
||||
if (tlb_flag(TLB_V6_I_ASID))
|
||||
asm("mcr p15, 0, %0, c8, c5, 2" : : "r" (asid) : "cc");
|
||||
if (tlb_flag(TLB_V7_UIS_ASID))
|
||||
tlb_op(TLB_V6_U_ASID, "c8, c7, 2", asid);
|
||||
tlb_op(TLB_V6_D_ASID, "c8, c6, 2", asid);
|
||||
tlb_op(TLB_V6_I_ASID, "c8, c5, 2", asid);
|
||||
#ifdef CONFIG_ARM_ERRATA_720789
|
||||
asm("mcr p15, 0, %0, c8, c3, 0" : : "r" (zero) : "cc");
|
||||
tlb_op(TLB_V7_UIS_ASID, "c8, c3, 0", zero);
|
||||
#else
|
||||
asm("mcr p15, 0, %0, c8, c3, 2" : : "r" (asid) : "cc");
|
||||
tlb_op(TLB_V7_UIS_ASID, "c8, c3, 2", asid);
|
||||
#endif
|
||||
|
||||
if (tlb_flag(TLB_BARRIER))
|
||||
|
@ -392,30 +396,23 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
|
|||
if (tlb_flag(TLB_WB))
|
||||
dsb();
|
||||
|
||||
if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) {
|
||||
if (tlb_flag(TLB_V3_PAGE))
|
||||
asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (uaddr) : "cc");
|
||||
if (tlb_flag(TLB_V4_U_PAGE))
|
||||
asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (uaddr) : "cc");
|
||||
if (tlb_flag(TLB_V4_D_PAGE))
|
||||
asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (uaddr) : "cc");
|
||||
if (tlb_flag(TLB_V4_I_PAGE))
|
||||
asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc");
|
||||
if (possible_tlb_flags & (TLB_V3_PAGE|TLB_V4_U_PAGE|TLB_V4_D_PAGE|TLB_V4_I_PAGE|TLB_V4_I_FULL) &&
|
||||
cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) {
|
||||
tlb_op(TLB_V3_PAGE, "c6, c0, 0", uaddr);
|
||||
tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", uaddr);
|
||||
tlb_op(TLB_V4_D_PAGE, "c8, c6, 1", uaddr);
|
||||
tlb_op(TLB_V4_I_PAGE, "c8, c5, 1", uaddr);
|
||||
if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL))
|
||||
asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
|
||||
}
|
||||
|
||||
if (tlb_flag(TLB_V6_U_PAGE))
|
||||
asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (uaddr) : "cc");
|
||||
if (tlb_flag(TLB_V6_D_PAGE))
|
||||
asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (uaddr) : "cc");
|
||||
if (tlb_flag(TLB_V6_I_PAGE))
|
||||
asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc");
|
||||
if (tlb_flag(TLB_V7_UIS_PAGE))
|
||||
tlb_op(TLB_V6_U_PAGE, "c8, c7, 1", uaddr);
|
||||
tlb_op(TLB_V6_D_PAGE, "c8, c6, 1", uaddr);
|
||||
tlb_op(TLB_V6_I_PAGE, "c8, c5, 1", uaddr);
|
||||
#ifdef CONFIG_ARM_ERRATA_720789
|
||||
asm("mcr p15, 0, %0, c8, c3, 3" : : "r" (uaddr & PAGE_MASK) : "cc");
|
||||
tlb_op(TLB_V7_UIS_PAGE, "c8, c3, 3", uaddr & PAGE_MASK);
|
||||
#else
|
||||
asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (uaddr) : "cc");
|
||||
tlb_op(TLB_V7_UIS_PAGE, "c8, c3, 1", uaddr);
|
||||
#endif
|
||||
|
||||
if (tlb_flag(TLB_BARRIER))
|
||||
|
@ -432,25 +429,17 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
|
|||
if (tlb_flag(TLB_WB))
|
||||
dsb();
|
||||
|
||||
if (tlb_flag(TLB_V3_PAGE))
|
||||
asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (kaddr) : "cc");
|
||||
if (tlb_flag(TLB_V4_U_PAGE))
|
||||
asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (kaddr) : "cc");
|
||||
if (tlb_flag(TLB_V4_D_PAGE))
|
||||
asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (kaddr) : "cc");
|
||||
if (tlb_flag(TLB_V4_I_PAGE))
|
||||
asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc");
|
||||
tlb_op(TLB_V3_PAGE, "c6, c0, 0", kaddr);
|
||||
tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", kaddr);
|
||||
tlb_op(TLB_V4_D_PAGE, "c8, c6, 1", kaddr);
|
||||
tlb_op(TLB_V4_I_PAGE, "c8, c5, 1", kaddr);
|
||||
if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL))
|
||||
asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
|
||||
|
||||
if (tlb_flag(TLB_V6_U_PAGE))
|
||||
asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (kaddr) : "cc");
|
||||
if (tlb_flag(TLB_V6_D_PAGE))
|
||||
asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (kaddr) : "cc");
|
||||
if (tlb_flag(TLB_V6_I_PAGE))
|
||||
asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc");
|
||||
if (tlb_flag(TLB_V7_UIS_PAGE))
|
||||
asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (kaddr) : "cc");
|
||||
tlb_op(TLB_V6_U_PAGE, "c8, c7, 1", kaddr);
|
||||
tlb_op(TLB_V6_D_PAGE, "c8, c6, 1", kaddr);
|
||||
tlb_op(TLB_V6_I_PAGE, "c8, c5, 1", kaddr);
|
||||
tlb_op(TLB_V7_UIS_PAGE, "c8, c3, 1", kaddr);
|
||||
|
||||
if (tlb_flag(TLB_BARRIER)) {
|
||||
dsb();
|
||||
|
@ -475,13 +464,8 @@ static inline void flush_pmd_entry(void *pmd)
|
|||
{
|
||||
const unsigned int __tlb_flag = __cpu_tlb_flags;
|
||||
|
||||
if (tlb_flag(TLB_DCLEAN))
|
||||
asm("mcr p15, 0, %0, c7, c10, 1 @ flush_pmd"
|
||||
: : "r" (pmd) : "cc");
|
||||
|
||||
if (tlb_flag(TLB_L2CLEAN_FR))
|
||||
asm("mcr p15, 1, %0, c15, c9, 1 @ L2 flush_pmd"
|
||||
: : "r" (pmd) : "cc");
|
||||
tlb_op(TLB_DCLEAN, "c7, c10, 1 @ flush_pmd", pmd);
|
||||
tlb_l2_op(TLB_L2CLEAN_FR, "c15, c9, 1 @ L2 flush_pmd", pmd);
|
||||
|
||||
if (tlb_flag(TLB_WB))
|
||||
dsb();
|
||||
|
@ -491,15 +475,11 @@ static inline void clean_pmd_entry(void *pmd)
|
|||
{
|
||||
const unsigned int __tlb_flag = __cpu_tlb_flags;
|
||||
|
||||
if (tlb_flag(TLB_DCLEAN))
|
||||
asm("mcr p15, 0, %0, c7, c10, 1 @ flush_pmd"
|
||||
: : "r" (pmd) : "cc");
|
||||
|
||||
if (tlb_flag(TLB_L2CLEAN_FR))
|
||||
asm("mcr p15, 1, %0, c15, c9, 1 @ L2 flush_pmd"
|
||||
: : "r" (pmd) : "cc");
|
||||
tlb_op(TLB_DCLEAN, "c7, c10, 1 @ flush_pmd", pmd);
|
||||
tlb_l2_op(TLB_L2CLEAN_FR, "c15, c9, 1 @ L2 flush_pmd", pmd);
|
||||
}
|
||||
|
||||
#undef tlb_op
|
||||
#undef tlb_flag
|
||||
#undef always_tlb_flags
|
||||
#undef possible_tlb_flags
|
||||
|
|
|
@ -46,7 +46,7 @@ static inline int in_exception_text(unsigned long ptr)
|
|||
return in ? : __in_irqentry_text(ptr);
|
||||
}
|
||||
|
||||
extern void __init early_trap_init(void);
|
||||
extern void __init early_trap_init(void *);
|
||||
extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame);
|
||||
extern void ptrace_break(struct task_struct *tsk, struct pt_regs *regs);
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@ AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
|
|||
|
||||
ifdef CONFIG_FUNCTION_TRACER
|
||||
CFLAGS_REMOVE_ftrace.o = -pg
|
||||
CFLAGS_REMOVE_insn.o = -pg
|
||||
CFLAGS_REMOVE_patch.o = -pg
|
||||
endif
|
||||
|
||||
CFLAGS_REMOVE_return_address.o = -pg
|
||||
|
@ -14,8 +16,8 @@ CFLAGS_REMOVE_return_address.o = -pg
|
|||
# Object file lists.
|
||||
|
||||
obj-y := elf.o entry-armv.o entry-common.o irq.o opcodes.o \
|
||||
process.o ptrace.o return_address.o setup.o signal.o \
|
||||
sys_arm.o stacktrace.o time.o traps.o
|
||||
process.o ptrace.o return_address.o sched_clock.o \
|
||||
setup.o signal.o stacktrace.o sys_arm.o time.o traps.o
|
||||
|
||||
obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += compat.o
|
||||
|
||||
|
@ -29,14 +31,14 @@ obj-$(CONFIG_ARTHUR) += arthur.o
|
|||
obj-$(CONFIG_ISA_DMA) += dma-isa.o
|
||||
obj-$(CONFIG_PCI) += bios32.o isa.o
|
||||
obj-$(CONFIG_ARM_CPU_SUSPEND) += sleep.o suspend.o
|
||||
obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o
|
||||
obj-$(CONFIG_SMP) += smp.o smp_tlb.o
|
||||
obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o
|
||||
obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o
|
||||
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
|
||||
obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
|
||||
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o insn.o
|
||||
obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o
|
||||
obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o
|
||||
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
|
||||
obj-$(CONFIG_KPROBES) += kprobes.o kprobes-common.o
|
||||
obj-$(CONFIG_KPROBES) += kprobes.o kprobes-common.o patch.o
|
||||
ifdef CONFIG_THUMB2_KERNEL
|
||||
obj-$(CONFIG_KPROBES) += kprobes-thumb.o
|
||||
else
|
||||
|
|
|
@ -100,7 +100,7 @@
|
|||
|
||||
#endif /* CONFIG_CPU_V6 */
|
||||
|
||||
#else
|
||||
#elif !defined(CONFIG_DEBUG_SEMIHOSTING)
|
||||
#include <mach/debug-macro.S>
|
||||
#endif /* CONFIG_DEBUG_ICEDCC */
|
||||
|
||||
|
@ -155,6 +155,8 @@ hexbuf: .space 16
|
|||
|
||||
.ltorg
|
||||
|
||||
#ifndef CONFIG_DEBUG_SEMIHOSTING
|
||||
|
||||
ENTRY(printascii)
|
||||
addruart_current r3, r1, r2
|
||||
b 2f
|
||||
|
@ -177,3 +179,24 @@ ENTRY(printch)
|
|||
mov r0, #0
|
||||
b 1b
|
||||
ENDPROC(printch)
|
||||
|
||||
#else
|
||||
|
||||
ENTRY(printascii)
|
||||
mov r1, r0
|
||||
mov r0, #0x04 @ SYS_WRITE0
|
||||
ARM( svc #0x123456 )
|
||||
THUMB( svc #0xab )
|
||||
mov pc, lr
|
||||
ENDPROC(printascii)
|
||||
|
||||
ENTRY(printch)
|
||||
adr r1, hexbuf
|
||||
strb r0, [r1]
|
||||
mov r0, #0x03 @ SYS_WRITEC
|
||||
ARM( svc #0x123456 )
|
||||
THUMB( svc #0xab )
|
||||
mov pc, lr
|
||||
ENDPROC(printch)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -16,10 +16,13 @@
|
|||
#include <linux/uaccess.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/opcodes.h>
|
||||
#include <asm/ftrace.h>
|
||||
|
||||
#include "insn.h"
|
||||
|
||||
#ifdef CONFIG_THUMB2_KERNEL
|
||||
#define NOP 0xeb04f85d /* pop.w {lr} */
|
||||
#define NOP 0xf85deb04 /* pop.w {lr} */
|
||||
#else
|
||||
#define NOP 0xe8bd4000 /* pop {lr} */
|
||||
#endif
|
||||
|
@ -60,76 +63,31 @@ static unsigned long adjust_address(struct dyn_ftrace *rec, unsigned long addr)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_THUMB2_KERNEL
|
||||
static unsigned long ftrace_gen_branch(unsigned long pc, unsigned long addr,
|
||||
bool link)
|
||||
{
|
||||
unsigned long s, j1, j2, i1, i2, imm10, imm11;
|
||||
unsigned long first, second;
|
||||
long offset;
|
||||
|
||||
offset = (long)addr - (long)(pc + 4);
|
||||
if (offset < -16777216 || offset > 16777214) {
|
||||
WARN_ON_ONCE(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
s = (offset >> 24) & 0x1;
|
||||
i1 = (offset >> 23) & 0x1;
|
||||
i2 = (offset >> 22) & 0x1;
|
||||
imm10 = (offset >> 12) & 0x3ff;
|
||||
imm11 = (offset >> 1) & 0x7ff;
|
||||
|
||||
j1 = (!i1) ^ s;
|
||||
j2 = (!i2) ^ s;
|
||||
|
||||
first = 0xf000 | (s << 10) | imm10;
|
||||
second = 0x9000 | (j1 << 13) | (j2 << 11) | imm11;
|
||||
if (link)
|
||||
second |= 1 << 14;
|
||||
|
||||
return (second << 16) | first;
|
||||
}
|
||||
#else
|
||||
static unsigned long ftrace_gen_branch(unsigned long pc, unsigned long addr,
|
||||
bool link)
|
||||
{
|
||||
unsigned long opcode = 0xea000000;
|
||||
long offset;
|
||||
|
||||
if (link)
|
||||
opcode |= 1 << 24;
|
||||
|
||||
offset = (long)addr - (long)(pc + 8);
|
||||
if (unlikely(offset < -33554432 || offset > 33554428)) {
|
||||
/* Can't generate branches that far (from ARM ARM). Ftrace
|
||||
* doesn't generate branches outside of kernel text.
|
||||
*/
|
||||
WARN_ON_ONCE(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
offset = (offset >> 2) & 0x00ffffff;
|
||||
|
||||
return opcode | offset;
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr)
|
||||
{
|
||||
return ftrace_gen_branch(pc, addr, true);
|
||||
return arm_gen_branch_link(pc, addr);
|
||||
}
|
||||
|
||||
static int ftrace_modify_code(unsigned long pc, unsigned long old,
|
||||
unsigned long new)
|
||||
unsigned long new, bool validate)
|
||||
{
|
||||
unsigned long replaced;
|
||||
|
||||
if (probe_kernel_read(&replaced, (void *)pc, MCOUNT_INSN_SIZE))
|
||||
return -EFAULT;
|
||||
if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
|
||||
old = __opcode_to_mem_thumb32(old);
|
||||
new = __opcode_to_mem_thumb32(new);
|
||||
} else {
|
||||
old = __opcode_to_mem_arm(old);
|
||||
new = __opcode_to_mem_arm(new);
|
||||
}
|
||||
|
||||
if (replaced != old)
|
||||
return -EINVAL;
|
||||
if (validate) {
|
||||
if (probe_kernel_read(&replaced, (void *)pc, MCOUNT_INSN_SIZE))
|
||||
return -EFAULT;
|
||||
|
||||
if (replaced != old)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (probe_kernel_write((void *)pc, &new, MCOUNT_INSN_SIZE))
|
||||
return -EPERM;
|
||||
|
@ -141,23 +99,21 @@ static int ftrace_modify_code(unsigned long pc, unsigned long old,
|
|||
|
||||
int ftrace_update_ftrace_func(ftrace_func_t func)
|
||||
{
|
||||
unsigned long pc, old;
|
||||
unsigned long pc;
|
||||
unsigned long new;
|
||||
int ret;
|
||||
|
||||
pc = (unsigned long)&ftrace_call;
|
||||
memcpy(&old, &ftrace_call, MCOUNT_INSN_SIZE);
|
||||
new = ftrace_call_replace(pc, (unsigned long)func);
|
||||
|
||||
ret = ftrace_modify_code(pc, old, new);
|
||||
ret = ftrace_modify_code(pc, 0, new, false);
|
||||
|
||||
#ifdef CONFIG_OLD_MCOUNT
|
||||
if (!ret) {
|
||||
pc = (unsigned long)&ftrace_call_old;
|
||||
memcpy(&old, &ftrace_call_old, MCOUNT_INSN_SIZE);
|
||||
new = ftrace_call_replace(pc, (unsigned long)func);
|
||||
|
||||
ret = ftrace_modify_code(pc, old, new);
|
||||
ret = ftrace_modify_code(pc, 0, new, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -172,7 +128,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
|
|||
old = ftrace_nop_replace(rec);
|
||||
new = ftrace_call_replace(ip, adjust_address(rec, addr));
|
||||
|
||||
return ftrace_modify_code(rec->ip, old, new);
|
||||
return ftrace_modify_code(rec->ip, old, new, true);
|
||||
}
|
||||
|
||||
int ftrace_make_nop(struct module *mod,
|
||||
|
@ -185,7 +141,7 @@ int ftrace_make_nop(struct module *mod,
|
|||
|
||||
old = ftrace_call_replace(ip, adjust_address(rec, addr));
|
||||
new = ftrace_nop_replace(rec);
|
||||
ret = ftrace_modify_code(ip, old, new);
|
||||
ret = ftrace_modify_code(ip, old, new, true);
|
||||
|
||||
#ifdef CONFIG_OLD_MCOUNT
|
||||
if (ret == -EINVAL && addr == MCOUNT_ADDR) {
|
||||
|
@ -193,7 +149,7 @@ int ftrace_make_nop(struct module *mod,
|
|||
|
||||
old = ftrace_call_replace(ip, adjust_address(rec, addr));
|
||||
new = ftrace_nop_replace(rec);
|
||||
ret = ftrace_modify_code(ip, old, new);
|
||||
ret = ftrace_modify_code(ip, old, new, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -249,12 +205,12 @@ static int __ftrace_modify_caller(unsigned long *callsite,
|
|||
{
|
||||
unsigned long caller_fn = (unsigned long) func;
|
||||
unsigned long pc = (unsigned long) callsite;
|
||||
unsigned long branch = ftrace_gen_branch(pc, caller_fn, false);
|
||||
unsigned long branch = arm_gen_branch(pc, caller_fn);
|
||||
unsigned long nop = 0xe1a00000; /* mov r0, r0 */
|
||||
unsigned long old = enable ? nop : branch;
|
||||
unsigned long new = enable ? branch : nop;
|
||||
|
||||
return ftrace_modify_code(pc, old, new);
|
||||
return ftrace_modify_code(pc, old, new, true);
|
||||
}
|
||||
|
||||
static int ftrace_modify_graph_caller(bool enable)
|
||||
|
|
|
@ -265,7 +265,7 @@ __create_page_tables:
|
|||
str r6, [r3]
|
||||
|
||||
#ifdef CONFIG_DEBUG_LL
|
||||
#ifndef CONFIG_DEBUG_ICEDCC
|
||||
#if !defined(CONFIG_DEBUG_ICEDCC) && !defined(CONFIG_DEBUG_SEMIHOSTING)
|
||||
/*
|
||||
* Map in IO space for serial debugging.
|
||||
* This allows debug messages to be output
|
||||
|
@ -297,10 +297,10 @@ __create_page_tables:
|
|||
cmp r0, r6
|
||||
blo 1b
|
||||
|
||||
#else /* CONFIG_DEBUG_ICEDCC */
|
||||
/* we don't need any serial debugging mappings for ICEDCC */
|
||||
#else /* CONFIG_DEBUG_ICEDCC || CONFIG_DEBUG_SEMIHOSTING */
|
||||
/* we don't need any serial debugging mappings */
|
||||
ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags
|
||||
#endif /* !CONFIG_DEBUG_ICEDCC */
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ARCH_NETWINDER) || defined(CONFIG_ARCH_CATS)
|
||||
/*
|
||||
|
|
61
arch/arm/kernel/insn.c
Normal file
61
arch/arm/kernel/insn.c
Normal file
|
@ -0,0 +1,61 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <asm/opcodes.h>
|
||||
|
||||
static unsigned long
|
||||
__arm_gen_branch_thumb2(unsigned long pc, unsigned long addr, bool link)
|
||||
{
|
||||
unsigned long s, j1, j2, i1, i2, imm10, imm11;
|
||||
unsigned long first, second;
|
||||
long offset;
|
||||
|
||||
offset = (long)addr - (long)(pc + 4);
|
||||
if (offset < -16777216 || offset > 16777214) {
|
||||
WARN_ON_ONCE(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
s = (offset >> 24) & 0x1;
|
||||
i1 = (offset >> 23) & 0x1;
|
||||
i2 = (offset >> 22) & 0x1;
|
||||
imm10 = (offset >> 12) & 0x3ff;
|
||||
imm11 = (offset >> 1) & 0x7ff;
|
||||
|
||||
j1 = (!i1) ^ s;
|
||||
j2 = (!i2) ^ s;
|
||||
|
||||
first = 0xf000 | (s << 10) | imm10;
|
||||
second = 0x9000 | (j1 << 13) | (j2 << 11) | imm11;
|
||||
if (link)
|
||||
second |= 1 << 14;
|
||||
|
||||
return __opcode_thumb32_compose(first, second);
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
__arm_gen_branch_arm(unsigned long pc, unsigned long addr, bool link)
|
||||
{
|
||||
unsigned long opcode = 0xea000000;
|
||||
long offset;
|
||||
|
||||
if (link)
|
||||
opcode |= 1 << 24;
|
||||
|
||||
offset = (long)addr - (long)(pc + 8);
|
||||
if (unlikely(offset < -33554432 || offset > 33554428)) {
|
||||
WARN_ON_ONCE(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
offset = (offset >> 2) & 0x00ffffff;
|
||||
|
||||
return opcode | offset;
|
||||
}
|
||||
|
||||
unsigned long
|
||||
__arm_gen_branch(unsigned long pc, unsigned long addr, bool link)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_THUMB2_KERNEL))
|
||||
return __arm_gen_branch_thumb2(pc, addr, link);
|
||||
else
|
||||
return __arm_gen_branch_arm(pc, addr, link);
|
||||
}
|
29
arch/arm/kernel/insn.h
Normal file
29
arch/arm/kernel/insn.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef __ASM_ARM_INSN_H
|
||||
#define __ASM_ARM_INSN_H
|
||||
|
||||
static inline unsigned long
|
||||
arm_gen_nop(void)
|
||||
{
|
||||
#ifdef CONFIG_THUMB2_KERNEL
|
||||
return 0xf3af8000; /* nop.w */
|
||||
#else
|
||||
return 0xe1a00000; /* mov r0, r0 */
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned long
|
||||
__arm_gen_branch(unsigned long pc, unsigned long addr, bool link);
|
||||
|
||||
static inline unsigned long
|
||||
arm_gen_branch(unsigned long pc, unsigned long addr)
|
||||
{
|
||||
return __arm_gen_branch(pc, addr, false);
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
arm_gen_branch_link(unsigned long pc, unsigned long addr)
|
||||
{
|
||||
return __arm_gen_branch(pc, addr, true);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -180,10 +180,7 @@ void migrate_irqs(void)
|
|||
local_irq_save(flags);
|
||||
|
||||
for_each_irq_desc(i, desc) {
|
||||
bool affinity_broken = false;
|
||||
|
||||
if (!desc)
|
||||
continue;
|
||||
bool affinity_broken;
|
||||
|
||||
raw_spin_lock(&desc->lock);
|
||||
affinity_broken = migrate_one_irq(desc);
|
||||
|
|
39
arch/arm/kernel/jump_label.c
Normal file
39
arch/arm/kernel/jump_label.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/jump_label.h>
|
||||
|
||||
#include "insn.h"
|
||||
#include "patch.h"
|
||||
|
||||
#ifdef HAVE_JUMP_LABEL
|
||||
|
||||
static void __arch_jump_label_transform(struct jump_entry *entry,
|
||||
enum jump_label_type type,
|
||||
bool is_static)
|
||||
{
|
||||
void *addr = (void *)entry->code;
|
||||
unsigned int insn;
|
||||
|
||||
if (type == JUMP_LABEL_ENABLE)
|
||||
insn = arm_gen_branch(entry->code, entry->target);
|
||||
else
|
||||
insn = arm_gen_nop();
|
||||
|
||||
if (is_static)
|
||||
__patch_text(addr, insn);
|
||||
else
|
||||
patch_text(addr, insn);
|
||||
}
|
||||
|
||||
void arch_jump_label_transform(struct jump_entry *entry,
|
||||
enum jump_label_type type)
|
||||
{
|
||||
__arch_jump_label_transform(entry, type, false);
|
||||
}
|
||||
|
||||
void arch_jump_label_transform_static(struct jump_entry *entry,
|
||||
enum jump_label_type type)
|
||||
{
|
||||
__arch_jump_label_transform(entry, type, true);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -29,6 +29,7 @@
|
|||
#include <asm/cacheflush.h>
|
||||
|
||||
#include "kprobes.h"
|
||||
#include "patch.h"
|
||||
|
||||
#define MIN_STACK_SIZE(addr) \
|
||||
min((unsigned long)MAX_STACK_SIZE, \
|
||||
|
@ -103,58 +104,34 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_THUMB2_KERNEL
|
||||
|
||||
/*
|
||||
* For a 32-bit Thumb breakpoint spanning two memory words we need to take
|
||||
* special precautions to insert the breakpoint atomically, especially on SMP
|
||||
* systems. This is achieved by calling this arming function using stop_machine.
|
||||
*/
|
||||
static int __kprobes set_t32_breakpoint(void *addr)
|
||||
{
|
||||
((u16 *)addr)[0] = KPROBE_THUMB32_BREAKPOINT_INSTRUCTION >> 16;
|
||||
((u16 *)addr)[1] = KPROBE_THUMB32_BREAKPOINT_INSTRUCTION & 0xffff;
|
||||
flush_insns(addr, 2*sizeof(u16));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __kprobes arch_arm_kprobe(struct kprobe *p)
|
||||
{
|
||||
uintptr_t addr = (uintptr_t)p->addr & ~1; /* Remove any Thumb flag */
|
||||
unsigned int brkp;
|
||||
void *addr;
|
||||
|
||||
if (!is_wide_instruction(p->opcode)) {
|
||||
*(u16 *)addr = KPROBE_THUMB16_BREAKPOINT_INSTRUCTION;
|
||||
flush_insns(addr, sizeof(u16));
|
||||
} else if (addr & 2) {
|
||||
/* A 32-bit instruction spanning two words needs special care */
|
||||
stop_machine(set_t32_breakpoint, (void *)addr, &cpu_online_map);
|
||||
if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) {
|
||||
/* Remove any Thumb flag */
|
||||
addr = (void *)((uintptr_t)p->addr & ~1);
|
||||
|
||||
if (is_wide_instruction(p->opcode))
|
||||
brkp = KPROBE_THUMB32_BREAKPOINT_INSTRUCTION;
|
||||
else
|
||||
brkp = KPROBE_THUMB16_BREAKPOINT_INSTRUCTION;
|
||||
} else {
|
||||
/* Word aligned 32-bit instruction can be written atomically */
|
||||
u32 bkp = KPROBE_THUMB32_BREAKPOINT_INSTRUCTION;
|
||||
#ifndef __ARMEB__ /* Swap halfwords for little-endian */
|
||||
bkp = (bkp >> 16) | (bkp << 16);
|
||||
#endif
|
||||
*(u32 *)addr = bkp;
|
||||
flush_insns(addr, sizeof(u32));
|
||||
kprobe_opcode_t insn = p->opcode;
|
||||
|
||||
addr = p->addr;
|
||||
brkp = KPROBE_ARM_BREAKPOINT_INSTRUCTION;
|
||||
|
||||
if (insn >= 0xe0000000)
|
||||
brkp |= 0xe0000000; /* Unconditional instruction */
|
||||
else
|
||||
brkp |= insn & 0xf0000000; /* Copy condition from insn */
|
||||
}
|
||||
|
||||
patch_text(addr, brkp);
|
||||
}
|
||||
|
||||
#else /* !CONFIG_THUMB2_KERNEL */
|
||||
|
||||
void __kprobes arch_arm_kprobe(struct kprobe *p)
|
||||
{
|
||||
kprobe_opcode_t insn = p->opcode;
|
||||
kprobe_opcode_t brkp = KPROBE_ARM_BREAKPOINT_INSTRUCTION;
|
||||
if (insn >= 0xe0000000)
|
||||
brkp |= 0xe0000000; /* Unconditional instruction */
|
||||
else
|
||||
brkp |= insn & 0xf0000000; /* Copy condition from insn */
|
||||
*p->addr = brkp;
|
||||
flush_insns(p->addr, sizeof(p->addr[0]));
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_THUMB2_KERNEL */
|
||||
|
||||
/*
|
||||
* The actual disarming is done here on each CPU and synchronized using
|
||||
* stop_machine. This synchronization is necessary on SMP to avoid removing
|
||||
|
@ -166,25 +143,10 @@ void __kprobes arch_arm_kprobe(struct kprobe *p)
|
|||
int __kprobes __arch_disarm_kprobe(void *p)
|
||||
{
|
||||
struct kprobe *kp = p;
|
||||
#ifdef CONFIG_THUMB2_KERNEL
|
||||
u16 *addr = (u16 *)((uintptr_t)kp->addr & ~1);
|
||||
kprobe_opcode_t insn = kp->opcode;
|
||||
unsigned int len;
|
||||
void *addr = (void *)((uintptr_t)kp->addr & ~1);
|
||||
|
||||
if (is_wide_instruction(insn)) {
|
||||
((u16 *)addr)[0] = insn>>16;
|
||||
((u16 *)addr)[1] = insn;
|
||||
len = 2*sizeof(u16);
|
||||
} else {
|
||||
((u16 *)addr)[0] = insn;
|
||||
len = sizeof(u16);
|
||||
}
|
||||
flush_insns(addr, len);
|
||||
__patch_text(addr, kp->opcode);
|
||||
|
||||
#else /* !CONFIG_THUMB2_KERNEL */
|
||||
*kp->addr = kp->opcode;
|
||||
flush_insns(kp->addr, sizeof(kp->addr[0]));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/irq.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/mmu_context.h>
|
||||
|
@ -53,6 +54,29 @@ void machine_crash_nonpanic_core(void *unused)
|
|||
cpu_relax();
|
||||
}
|
||||
|
||||
static void machine_kexec_mask_interrupts(void)
|
||||
{
|
||||
unsigned int i;
|
||||
struct irq_desc *desc;
|
||||
|
||||
for_each_irq_desc(i, desc) {
|
||||
struct irq_chip *chip;
|
||||
|
||||
chip = irq_desc_get_chip(desc);
|
||||
if (!chip)
|
||||
continue;
|
||||
|
||||
if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
|
||||
chip->irq_eoi(&desc->irq_data);
|
||||
|
||||
if (chip->irq_mask)
|
||||
chip->irq_mask(&desc->irq_data);
|
||||
|
||||
if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
|
||||
chip->irq_disable(&desc->irq_data);
|
||||
}
|
||||
}
|
||||
|
||||
void machine_crash_shutdown(struct pt_regs *regs)
|
||||
{
|
||||
unsigned long msecs;
|
||||
|
@ -70,6 +94,7 @@ void machine_crash_shutdown(struct pt_regs *regs)
|
|||
printk(KERN_WARNING "Non-crashing CPUs did not react to IPI\n");
|
||||
|
||||
crash_save_cpu(regs, smp_processor_id());
|
||||
machine_kexec_mask_interrupts();
|
||||
|
||||
printk(KERN_INFO "Loading crashdump kernel...\n");
|
||||
}
|
||||
|
|
75
arch/arm/kernel/patch.c
Normal file
75
arch/arm/kernel/patch.c
Normal file
|
@ -0,0 +1,75 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/kprobes.h>
|
||||
#include <linux/stop_machine.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/smp_plat.h>
|
||||
#include <asm/opcodes.h>
|
||||
|
||||
#include "patch.h"
|
||||
|
||||
struct patch {
|
||||
void *addr;
|
||||
unsigned int insn;
|
||||
};
|
||||
|
||||
void __kprobes __patch_text(void *addr, unsigned int insn)
|
||||
{
|
||||
bool thumb2 = IS_ENABLED(CONFIG_THUMB2_KERNEL);
|
||||
int size;
|
||||
|
||||
if (thumb2 && __opcode_is_thumb16(insn)) {
|
||||
*(u16 *)addr = __opcode_to_mem_thumb16(insn);
|
||||
size = sizeof(u16);
|
||||
} else if (thumb2 && ((uintptr_t)addr & 2)) {
|
||||
u16 first = __opcode_thumb32_first(insn);
|
||||
u16 second = __opcode_thumb32_second(insn);
|
||||
u16 *addrh = addr;
|
||||
|
||||
addrh[0] = __opcode_to_mem_thumb16(first);
|
||||
addrh[1] = __opcode_to_mem_thumb16(second);
|
||||
|
||||
size = sizeof(u32);
|
||||
} else {
|
||||
if (thumb2)
|
||||
insn = __opcode_to_mem_thumb32(insn);
|
||||
else
|
||||
insn = __opcode_to_mem_arm(insn);
|
||||
|
||||
*(u32 *)addr = insn;
|
||||
size = sizeof(u32);
|
||||
}
|
||||
|
||||
flush_icache_range((uintptr_t)(addr),
|
||||
(uintptr_t)(addr) + size);
|
||||
}
|
||||
|
||||
static int __kprobes patch_text_stop_machine(void *data)
|
||||
{
|
||||
struct patch *patch = data;
|
||||
|
||||
__patch_text(patch->addr, patch->insn);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __kprobes patch_text(void *addr, unsigned int insn)
|
||||
{
|
||||
struct patch patch = {
|
||||
.addr = addr,
|
||||
.insn = insn,
|
||||
};
|
||||
|
||||
if (cache_ops_need_broadcast()) {
|
||||
stop_machine(patch_text_stop_machine, &patch, cpu_online_mask);
|
||||
} else {
|
||||
bool straddles_word = IS_ENABLED(CONFIG_THUMB2_KERNEL)
|
||||
&& __opcode_is_thumb32(insn)
|
||||
&& ((uintptr_t)addr & 2);
|
||||
|
||||
if (straddles_word)
|
||||
stop_machine(patch_text_stop_machine, &patch, NULL);
|
||||
else
|
||||
__patch_text(addr, insn);
|
||||
}
|
||||
}
|
7
arch/arm/kernel/patch.h
Normal file
7
arch/arm/kernel/patch.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ifndef _ARM_KERNEL_PATCH_H
|
||||
#define _ARM_KERNEL_PATCH_H
|
||||
|
||||
void patch_text(void *addr, unsigned int insn);
|
||||
void __patch_text(void *addr, unsigned int insn);
|
||||
|
||||
#endif
|
|
@ -738,6 +738,9 @@ init_hw_perf_events(void)
|
|||
case 0xC0F0: /* Cortex-A15 */
|
||||
cpu_pmu = armv7_a15_pmu_init();
|
||||
break;
|
||||
case 0xC070: /* Cortex-A7 */
|
||||
cpu_pmu = armv7_a7_pmu_init();
|
||||
break;
|
||||
}
|
||||
/* Intel CPUs [xscale]. */
|
||||
} else if (0x69 == implementor) {
|
||||
|
|
|
@ -609,6 +609,130 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
|||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Cortex-A7 HW events mapping
|
||||
*/
|
||||
static const unsigned armv7_a7_perf_map[PERF_COUNT_HW_MAX] = {
|
||||
[PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
|
||||
[PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
|
||||
[PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
|
||||
[PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
|
||||
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
|
||||
[PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
|
||||
[PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES,
|
||||
[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = HW_OP_UNSUPPORTED,
|
||||
[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED,
|
||||
};
|
||||
|
||||
static const unsigned armv7_a7_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
||||
[PERF_COUNT_HW_CACHE_OP_MAX]
|
||||
[PERF_COUNT_HW_CACHE_RESULT_MAX] = {
|
||||
[C(L1D)] = {
|
||||
/*
|
||||
* The performance counters don't differentiate between read
|
||||
* and write accesses/misses so this isn't strictly correct,
|
||||
* but it's the best we can do. Writes and reads get
|
||||
* combined.
|
||||
*/
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
|
||||
},
|
||||
},
|
||||
[C(L1I)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
|
||||
},
|
||||
},
|
||||
[C(LL)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_CACHE_ACCESS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_CACHE_ACCESS,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
|
||||
},
|
||||
},
|
||||
[C(DTLB)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
|
||||
},
|
||||
},
|
||||
[C(ITLB)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
|
||||
},
|
||||
},
|
||||
[C(BPU)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
|
||||
[C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
|
||||
},
|
||||
},
|
||||
[C(NODE)] = {
|
||||
[C(OP_READ)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
|
||||
},
|
||||
[C(OP_WRITE)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
|
||||
},
|
||||
[C(OP_PREFETCH)] = {
|
||||
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Perf Events' indices
|
||||
*/
|
||||
|
@ -1104,6 +1228,12 @@ static int armv7_a15_map_event(struct perf_event *event)
|
|||
&armv7_a15_perf_cache_map, 0xFF);
|
||||
}
|
||||
|
||||
static int armv7_a7_map_event(struct perf_event *event)
|
||||
{
|
||||
return map_cpu_event(event, &armv7_a7_perf_map,
|
||||
&armv7_a7_perf_cache_map, 0xFF);
|
||||
}
|
||||
|
||||
static struct arm_pmu armv7pmu = {
|
||||
.handle_irq = armv7pmu_handle_irq,
|
||||
.enable = armv7pmu_enable_event,
|
||||
|
@ -1164,6 +1294,16 @@ static struct arm_pmu *__init armv7_a15_pmu_init(void)
|
|||
armv7pmu.set_event_filter = armv7pmu_set_event_filter;
|
||||
return &armv7pmu;
|
||||
}
|
||||
|
||||
static struct arm_pmu *__init armv7_a7_pmu_init(void)
|
||||
{
|
||||
armv7pmu.id = ARM_PERF_PMU_ID_CA7;
|
||||
armv7pmu.name = "ARMv7 Cortex-A7";
|
||||
armv7pmu.map_event = armv7_a7_map_event;
|
||||
armv7pmu.num_events = armv7_read_num_pmnc_events();
|
||||
armv7pmu.set_event_filter = armv7pmu_set_event_filter;
|
||||
return &armv7pmu;
|
||||
}
|
||||
#else
|
||||
static struct arm_pmu *__init armv7_a8_pmu_init(void)
|
||||
{
|
||||
|
@ -1184,4 +1324,9 @@ static struct arm_pmu *__init armv7_a15_pmu_init(void)
|
|||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct arm_pmu *__init armv7_a7_pmu_init(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif /* CONFIG_CPU_V7 */
|
||||
|
|
|
@ -528,21 +528,39 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
|
|||
#ifdef CONFIG_MMU
|
||||
/*
|
||||
* The vectors page is always readable from user space for the
|
||||
* atomic helpers and the signal restart code. Let's declare a mapping
|
||||
* for it so it is visible through ptrace and /proc/<pid>/mem.
|
||||
* atomic helpers and the signal restart code. Insert it into the
|
||||
* gate_vma so that it is visible through ptrace and /proc/<pid>/mem.
|
||||
*/
|
||||
static struct vm_area_struct gate_vma;
|
||||
|
||||
int vectors_user_mapping(void)
|
||||
static int __init gate_vma_init(void)
|
||||
{
|
||||
struct mm_struct *mm = current->mm;
|
||||
return install_special_mapping(mm, 0xffff0000, PAGE_SIZE,
|
||||
VM_READ | VM_EXEC |
|
||||
VM_MAYREAD | VM_MAYEXEC | VM_RESERVED,
|
||||
NULL);
|
||||
gate_vma.vm_start = 0xffff0000;
|
||||
gate_vma.vm_end = 0xffff0000 + PAGE_SIZE;
|
||||
gate_vma.vm_page_prot = PAGE_READONLY_EXEC;
|
||||
gate_vma.vm_flags = VM_READ | VM_EXEC |
|
||||
VM_MAYREAD | VM_MAYEXEC;
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(gate_vma_init);
|
||||
|
||||
struct vm_area_struct *get_gate_vma(struct mm_struct *mm)
|
||||
{
|
||||
return &gate_vma;
|
||||
}
|
||||
|
||||
int in_gate_area(struct mm_struct *mm, unsigned long addr)
|
||||
{
|
||||
return (addr >= gate_vma.vm_start) && (addr < gate_vma.vm_end);
|
||||
}
|
||||
|
||||
int in_gate_area_no_mm(unsigned long addr)
|
||||
{
|
||||
return in_gate_area(NULL, addr);
|
||||
}
|
||||
|
||||
const char *arch_vma_name(struct vm_area_struct *vma)
|
||||
{
|
||||
return (vma->vm_start == 0xffff0000) ? "[vectors]" : NULL;
|
||||
return (vma == &gate_vma) ? "[vectors]" : NULL;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <linux/jiffies.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
#include <linux/timer.h>
|
||||
|
||||
#include <asm/sched_clock.h>
|
||||
|
@ -164,3 +165,20 @@ void __init sched_clock_postinit(void)
|
|||
|
||||
sched_clock_poll(sched_clock_timer.data);
|
||||
}
|
||||
|
||||
static int sched_clock_suspend(void)
|
||||
{
|
||||
sched_clock_poll(sched_clock_timer.data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct syscore_ops sched_clock_ops = {
|
||||
.suspend = sched_clock_suspend,
|
||||
};
|
||||
|
||||
static int __init sched_clock_syscore_init(void)
|
||||
{
|
||||
register_syscore_ops(&sched_clock_ops);
|
||||
return 0;
|
||||
}
|
||||
device_initcall(sched_clock_syscore_init);
|
||||
|
|
|
@ -976,7 +976,6 @@ void __init setup_arch(char **cmdline_p)
|
|||
conswitchp = &dummy_con;
|
||||
#endif
|
||||
#endif
|
||||
early_trap_init();
|
||||
|
||||
if (mdesc->init_early)
|
||||
mdesc->init_early();
|
||||
|
|
|
@ -66,12 +66,13 @@ const unsigned long syscall_restart_code[2] = {
|
|||
*/
|
||||
asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask)
|
||||
{
|
||||
mask &= _BLOCKABLE;
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
sigset_t blocked;
|
||||
|
||||
current->saved_sigmask = current->blocked;
|
||||
siginitset(¤t->blocked, mask);
|
||||
recalc_sigpending();
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
|
||||
mask &= _BLOCKABLE;
|
||||
siginitset(&blocked, mask);
|
||||
set_current_blocked(&blocked);
|
||||
|
||||
current->state = TASK_INTERRUPTIBLE;
|
||||
schedule();
|
||||
|
@ -280,10 +281,7 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf)
|
|||
err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
|
||||
if (err == 0) {
|
||||
sigdelsetmask(&set, ~_BLOCKABLE);
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
current->blocked = set;
|
||||
recalc_sigpending();
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
set_current_blocked(&set);
|
||||
}
|
||||
|
||||
__get_user_error(regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err);
|
||||
|
@ -636,13 +634,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
|
|||
/*
|
||||
* Block the signal if we were successful.
|
||||
*/
|
||||
spin_lock_irq(&tsk->sighand->siglock);
|
||||
sigorsets(&tsk->blocked, &tsk->blocked,
|
||||
&ka->sa.sa_mask);
|
||||
if (!(ka->sa.sa_flags & SA_NODEFER))
|
||||
sigaddset(&tsk->blocked, sig);
|
||||
recalc_sigpending();
|
||||
spin_unlock_irq(&tsk->sighand->siglock);
|
||||
block_sigmask(ka, sig);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -58,6 +58,8 @@ enum ipi_msg_type {
|
|||
IPI_CPU_STOP,
|
||||
};
|
||||
|
||||
static DECLARE_COMPLETION(cpu_running);
|
||||
|
||||
int __cpuinit __cpu_up(unsigned int cpu)
|
||||
{
|
||||
struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu);
|
||||
|
@ -98,20 +100,12 @@ int __cpuinit __cpu_up(unsigned int cpu)
|
|||
*/
|
||||
ret = boot_secondary(cpu, idle);
|
||||
if (ret == 0) {
|
||||
unsigned long timeout;
|
||||
|
||||
/*
|
||||
* CPU was successfully started, wait for it
|
||||
* to come online or time out.
|
||||
*/
|
||||
timeout = jiffies + HZ;
|
||||
while (time_before(jiffies, timeout)) {
|
||||
if (cpu_online(cpu))
|
||||
break;
|
||||
|
||||
udelay(10);
|
||||
barrier();
|
||||
}
|
||||
wait_for_completion_timeout(&cpu_running,
|
||||
msecs_to_jiffies(1000));
|
||||
|
||||
if (!cpu_online(cpu)) {
|
||||
pr_crit("CPU%u: failed to come online\n", cpu);
|
||||
|
@ -288,9 +282,10 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
|
|||
/*
|
||||
* OK, now it's safe to let the boot CPU continue. Wait for
|
||||
* the CPU migration code to notice that the CPU is online
|
||||
* before we continue.
|
||||
* before we continue - which happens after __cpu_up returns.
|
||||
*/
|
||||
set_cpu_online(cpu, true);
|
||||
complete(&cpu_running);
|
||||
|
||||
/*
|
||||
* Setup the percpu timer for this CPU.
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
#include <linux/timer.h>
|
||||
#include <linux/irq.h>
|
||||
|
||||
#include <linux/mc146818rtc.h>
|
||||
|
||||
#include <asm/leds.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/sched_clock.h>
|
||||
|
@ -149,8 +147,6 @@ void __init time_init(void)
|
|||
{
|
||||
system_timer = machine_desc->timer;
|
||||
system_timer->init();
|
||||
#ifdef CONFIG_HAVE_SCHED_CLOCK
|
||||
sched_clock_postinit();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -227,6 +227,11 @@ void show_stack(struct task_struct *tsk, unsigned long *sp)
|
|||
#else
|
||||
#define S_SMP ""
|
||||
#endif
|
||||
#ifdef CONFIG_THUMB2_KERNEL
|
||||
#define S_ISA " THUMB2"
|
||||
#else
|
||||
#define S_ISA " ARM"
|
||||
#endif
|
||||
|
||||
static int __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
|
||||
{
|
||||
|
@ -234,8 +239,8 @@ static int __die(const char *str, int err, struct thread_info *thread, struct pt
|
|||
static int die_counter;
|
||||
int ret;
|
||||
|
||||
printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n",
|
||||
str, err, ++die_counter);
|
||||
printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP
|
||||
S_ISA "\n", str, err, ++die_counter);
|
||||
|
||||
/* trap and error numbers are mostly meaningless on ARM */
|
||||
ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV);
|
||||
|
@ -784,18 +789,16 @@ static void __init kuser_get_tls_init(unsigned long vectors)
|
|||
memcpy((void *)vectors + 0xfe0, (void *)vectors + 0xfe8, 4);
|
||||
}
|
||||
|
||||
void __init early_trap_init(void)
|
||||
void __init early_trap_init(void *vectors_base)
|
||||
{
|
||||
#if defined(CONFIG_CPU_USE_DOMAINS)
|
||||
unsigned long vectors = CONFIG_VECTORS_BASE;
|
||||
#else
|
||||
unsigned long vectors = (unsigned long)vectors_page;
|
||||
#endif
|
||||
unsigned long vectors = (unsigned long)vectors_base;
|
||||
extern char __stubs_start[], __stubs_end[];
|
||||
extern char __vectors_start[], __vectors_end[];
|
||||
extern char __kuser_helper_start[], __kuser_helper_end[];
|
||||
int kuser_sz = __kuser_helper_end - __kuser_helper_start;
|
||||
|
||||
vectors_page = vectors_base;
|
||||
|
||||
/*
|
||||
* Copy the vectors, stubs and kuser helpers (in entry-armv.S)
|
||||
* into the vector page, mapped at 0xffff0000, and ensure these
|
||||
|
|
|
@ -19,11 +19,14 @@
|
|||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <asm/sched_clock.h>
|
||||
#include <asm/mach/irq.h>
|
||||
#include <asm/mach/time.h>
|
||||
|
||||
#include <mach/cputype.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/time.h>
|
||||
|
||||
#include "clock.h"
|
||||
|
||||
static struct clock_event_device clockevent_davinci;
|
||||
|
@ -272,19 +275,9 @@ static cycle_t read_cycles(struct clocksource *cs)
|
|||
return (cycles_t)timer32_read(t);
|
||||
}
|
||||
|
||||
/*
|
||||
* Kernel assumes that sched_clock can be called early but may not have
|
||||
* things ready yet.
|
||||
*/
|
||||
static cycle_t read_dummy(struct clocksource *cs)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static struct clocksource clocksource_davinci = {
|
||||
.rating = 300,
|
||||
.read = read_dummy,
|
||||
.read = read_cycles,
|
||||
.mask = CLOCKSOURCE_MASK(32),
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
};
|
||||
|
@ -292,12 +285,9 @@ static struct clocksource clocksource_davinci = {
|
|||
/*
|
||||
* Overwrite weak default sched_clock with something more precise
|
||||
*/
|
||||
unsigned long long notrace sched_clock(void)
|
||||
static u32 notrace davinci_read_sched_clock(void)
|
||||
{
|
||||
const cycle_t cyc = clocksource_davinci.read(&clocksource_davinci);
|
||||
|
||||
return clocksource_cyc2ns(cyc, clocksource_davinci.mult,
|
||||
clocksource_davinci.shift);
|
||||
return timer32_read(&timers[TID_CLOCKSOURCE]);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -397,12 +387,14 @@ static void __init davinci_timer_init(void)
|
|||
davinci_clock_tick_rate = clk_get_rate(timer_clk);
|
||||
|
||||
/* setup clocksource */
|
||||
clocksource_davinci.read = read_cycles;
|
||||
clocksource_davinci.name = id_to_name[clocksource_id];
|
||||
if (clocksource_register_hz(&clocksource_davinci,
|
||||
davinci_clock_tick_rate))
|
||||
printk(err, clocksource_davinci.name);
|
||||
|
||||
setup_sched_clock(davinci_read_sched_clock, 32,
|
||||
davinci_clock_tick_rate);
|
||||
|
||||
/* setup clockevent */
|
||||
clockevent_davinci.name = id_to_name[timers[TID_CLOCKEVENT].id];
|
||||
clockevent_davinci.mult = div_sc(davinci_clock_tick_rate, NSEC_PER_SEC,
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/time.h>
|
||||
#include <mach/irqs.h>
|
||||
|
||||
#include "core.h"
|
||||
#include "sysregs.h"
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
#ifndef __MACH_IRQS_H
|
||||
#define __MACH_IRQS_H
|
||||
|
||||
#define NR_IRQS 192
|
||||
|
||||
#endif
|
|
@ -25,8 +25,9 @@
|
|||
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/platform.h>
|
||||
#include <asm/irq.h>
|
||||
#include <mach/cm.h>
|
||||
#include <mach/irqs.h>
|
||||
|
||||
#include <asm/leds.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/time.h>
|
||||
|
|
|
@ -78,5 +78,6 @@
|
|||
#define IRQ_SIC_CP_LMINT7 46
|
||||
#define IRQ_SIC_END 46
|
||||
|
||||
#define NR_IRQS 47
|
||||
#define NR_IRQS_INTEGRATOR_AP 34
|
||||
#define NR_IRQS_INTEGRATOR_CP 47
|
||||
|
||||
|
|
|
@ -38,12 +38,13 @@
|
|||
#include <mach/hardware.h>
|
||||
#include <mach/platform.h>
|
||||
#include <asm/hardware/arm_timer.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/param.h> /* HZ */
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/sched_clock.h>
|
||||
|
||||
#include <mach/lm.h>
|
||||
#include <mach/irqs.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/irq.h>
|
||||
|
@ -325,6 +326,11 @@ static void __init ap_init(void)
|
|||
|
||||
static unsigned long timer_reload;
|
||||
|
||||
static u32 notrace integrator_read_sched_clock(void)
|
||||
{
|
||||
return -readl((void __iomem *) TIMER2_VA_BASE + TIMER_VALUE);
|
||||
}
|
||||
|
||||
static void integrator_clocksource_init(unsigned long inrate)
|
||||
{
|
||||
void __iomem *base = (void __iomem *)TIMER2_VA_BASE;
|
||||
|
@ -341,6 +347,7 @@ static void integrator_clocksource_init(unsigned long inrate)
|
|||
|
||||
clocksource_mmio_init(base + TIMER_VALUE, "timer2",
|
||||
rate, 200, 16, clocksource_mmio_readl_down);
|
||||
setup_sched_clock(integrator_read_sched_clock, 16, rate);
|
||||
}
|
||||
|
||||
static void __iomem * const clkevt_base = (void __iomem *)TIMER1_VA_BASE;
|
||||
|
@ -468,6 +475,7 @@ MACHINE_START(INTEGRATOR, "ARM-Integrator")
|
|||
.atag_offset = 0x100,
|
||||
.reserve = integrator_reserve,
|
||||
.map_io = ap_map_io,
|
||||
.nr_irqs = NR_IRQS_INTEGRATOR_AP,
|
||||
.init_early = integrator_init_early,
|
||||
.init_irq = ap_init_irq,
|
||||
.timer = &ap_timer,
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/platform.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/hardware/arm_timer.h>
|
||||
|
@ -34,6 +33,7 @@
|
|||
|
||||
#include <mach/cm.h>
|
||||
#include <mach/lm.h>
|
||||
#include <mach/irqs.h>
|
||||
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/irq.h>
|
||||
|
@ -464,6 +464,7 @@ MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
|
|||
.atag_offset = 0x100,
|
||||
.reserve = integrator_reserve,
|
||||
.map_io = intcp_map_io,
|
||||
.nr_irqs = NR_IRQS_INTEGRATOR_CP,
|
||||
.init_early = intcp_init_early,
|
||||
.init_irq = intcp_init_irq,
|
||||
.timer = &cp_timer,
|
||||
|
|
|
@ -26,10 +26,11 @@
|
|||
#include <linux/interrupt.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <asm/mach/pci.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
#include <mach/irqs.h>
|
||||
|
||||
/*
|
||||
* A small note about bridges and interrupts. The DECchip 21050 (and
|
||||
* later) adheres to the PCI-PCI bridge specification. This says that
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/platform.h>
|
||||
#include <asm/irq.h>
|
||||
#include <mach/irqs.h>
|
||||
|
||||
#include <asm/signal.h>
|
||||
#include <asm/mach/pci.h>
|
||||
#include <asm/irq_regs.h>
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <mach/addr-map.h>
|
||||
#include <mach/mfp-pxa168.h>
|
||||
#include <mach/pxa168.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <video/pxa168fb.h>
|
||||
#include <linux/input.h>
|
||||
#include <plat/pxa27x_keypad.h>
|
||||
|
@ -239,7 +240,7 @@ static void __init common_init(void)
|
|||
|
||||
MACHINE_START(ASPENITE, "PXA168-based Aspenite Development Platform")
|
||||
.map_io = mmp_map_io,
|
||||
.nr_irqs = IRQ_BOARD_START,
|
||||
.nr_irqs = MMP_NR_IRQS,
|
||||
.init_irq = pxa168_init_irq,
|
||||
.timer = &pxa168_timer,
|
||||
.init_machine = common_init,
|
||||
|
@ -248,7 +249,7 @@ MACHINE_END
|
|||
|
||||
MACHINE_START(ZYLONITE2, "PXA168-based Zylonite2 Development Platform")
|
||||
.map_io = mmp_map_io,
|
||||
.nr_irqs = IRQ_BOARD_START,
|
||||
.nr_irqs = MMP_NR_IRQS,
|
||||
.init_irq = pxa168_init_irq,
|
||||
.timer = &pxa168_timer,
|
||||
.init_machine = common_init,
|
||||
|
|
|
@ -43,6 +43,7 @@ static void __init avengers_lite_init(void)
|
|||
|
||||
MACHINE_START(AVENGERS_LITE, "PXA168 Avengers lite Development Platform")
|
||||
.map_io = mmp_map_io,
|
||||
.nr_irqs = MMP_NR_IRQS,
|
||||
.init_irq = pxa168_init_irq,
|
||||
.timer = &pxa168_timer,
|
||||
.init_machine = avengers_lite_init,
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
#define BROWNSTONE_NR_IRQS (IRQ_BOARD_START + 40)
|
||||
#define BROWNSTONE_NR_IRQS (MMP_NR_IRQS + 40)
|
||||
|
||||
#define GPIO_5V_ENABLE (89)
|
||||
|
||||
|
@ -158,7 +158,7 @@ static struct platform_device brownstone_v_5vp_device = {
|
|||
};
|
||||
|
||||
static struct max8925_platform_data brownstone_max8925_info = {
|
||||
.irq_base = IRQ_BOARD_START,
|
||||
.irq_base = MMP_NR_IRQS,
|
||||
};
|
||||
|
||||
static struct i2c_board_info brownstone_twsi1_info[] = {
|
||||
|
|
|
@ -23,10 +23,11 @@
|
|||
#include <mach/addr-map.h>
|
||||
#include <mach/mfp-mmp2.h>
|
||||
#include <mach/mmp2.h>
|
||||
#include <mach/irqs.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define FLINT_NR_IRQS (IRQ_BOARD_START + 48)
|
||||
#define FLINT_NR_IRQS (MMP_NR_IRQS + 48)
|
||||
|
||||
static unsigned long flint_pin_config[] __initdata = {
|
||||
/* UART1 */
|
||||
|
|
|
@ -191,7 +191,7 @@ static void __init gplugd_init(void)
|
|||
|
||||
MACHINE_START(GPLUGD, "PXA168-based GuruPlug Display (gplugD) Platform")
|
||||
.map_io = mmp_map_io,
|
||||
.nr_irqs = IRQ_BOARD_START,
|
||||
.nr_irqs = MMP_NR_IRQS,
|
||||
.init_irq = pxa168_init_irq,
|
||||
.timer = &pxa168_timer,
|
||||
.init_machine = gplugd_init,
|
||||
|
|
|
@ -223,7 +223,6 @@
|
|||
#define MMP_GPIO_TO_IRQ(gpio) (IRQ_GPIO_START + (gpio))
|
||||
|
||||
#define IRQ_BOARD_START (IRQ_GPIO_START + MMP_NR_BUILTIN_GPIO)
|
||||
|
||||
#define NR_IRQS (IRQ_BOARD_START)
|
||||
#define MMP_NR_IRQS IRQ_BOARD_START
|
||||
|
||||
#endif /* __ASM_MACH_IRQS_H */
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <linux/irq.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <mach/irqs.h>
|
||||
#include <mach/regs-icu.h>
|
||||
#include <mach/mmp2.h>
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <linux/mfd/max8925.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include <mach/irqs.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <mach/addr-map.h>
|
||||
|
@ -27,7 +28,7 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
#define JASPER_NR_IRQS (IRQ_BOARD_START + 48)
|
||||
#define JASPER_NR_IRQS (MMP_NR_IRQS + 48)
|
||||
|
||||
static unsigned long jasper_pin_config[] __initdata = {
|
||||
/* UART1 */
|
||||
|
@ -135,7 +136,7 @@ static struct max8925_power_pdata jasper_power_data = {
|
|||
static struct max8925_platform_data jasper_max8925_info = {
|
||||
.backlight = &jasper_backlight_data,
|
||||
.power = &jasper_power_data,
|
||||
.irq_base = IRQ_BOARD_START,
|
||||
.irq_base = MMP_NR_IRQS,
|
||||
};
|
||||
|
||||
static struct i2c_board_info jasper_twsi1_info[] = {
|
||||
|
|
|
@ -101,6 +101,7 @@ static void __init tavorevb_init(void)
|
|||
|
||||
MACHINE_START(TAVOREVB, "PXA910 Evaluation Board (aka TavorEVB)")
|
||||
.map_io = mmp_map_io,
|
||||
.nr_irqs = MMP_NR_IRQS,
|
||||
.init_irq = pxa910_init_irq,
|
||||
.timer = &pxa910_timer,
|
||||
.init_machine = tavorevb_init,
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <mach/mfp-pxa168.h>
|
||||
#include <mach/pxa168.h>
|
||||
#include <mach/teton_bga.h>
|
||||
#include <mach/irqs.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
@ -83,7 +84,7 @@ static void __init teton_bga_init(void)
|
|||
|
||||
MACHINE_START(TETON_BGA, "PXA168-based Teton BGA Development Platform")
|
||||
.map_io = mmp_map_io,
|
||||
.nr_irqs = IRQ_BOARD_START,
|
||||
.nr_irqs = MMP_NR_IRQS,
|
||||
.init_irq = pxa168_init_irq,
|
||||
.timer = &pxa168_timer,
|
||||
.init_machine = teton_bga_init,
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
* 16 board interrupts -- PCA9575 GPIO expander
|
||||
* 24 board interrupts -- 88PM860x PMIC
|
||||
*/
|
||||
#define TTCDKB_NR_IRQS (IRQ_BOARD_START + 16 + 16 + 24)
|
||||
#define TTCDKB_NR_IRQS (MMP_NR_IRQS + 16 + 16 + 24)
|
||||
|
||||
static unsigned long ttc_dkb_pin_config[] __initdata = {
|
||||
/* UART2 */
|
||||
|
@ -131,7 +131,7 @@ static struct platform_device *ttc_dkb_devices[] = {
|
|||
static struct pca953x_platform_data max7312_data[] = {
|
||||
{
|
||||
.gpio_base = TTCDKB_GPIO_EXT0(0),
|
||||
.irq_base = IRQ_BOARD_START,
|
||||
.irq_base = MMP_NR_IRQS,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <asm/mach/time.h>
|
||||
#include <asm/hardware/gic.h>
|
||||
#include <asm/localtimer.h>
|
||||
#include <asm/sched_clock.h>
|
||||
|
||||
#include <mach/msm_iomap.h>
|
||||
#include <mach/cpu.h>
|
||||
|
@ -105,12 +106,12 @@ static union {
|
|||
|
||||
static void __iomem *source_base;
|
||||
|
||||
static cycle_t msm_read_timer_count(struct clocksource *cs)
|
||||
static notrace cycle_t msm_read_timer_count(struct clocksource *cs)
|
||||
{
|
||||
return readl_relaxed(source_base + TIMER_COUNT_VAL);
|
||||
}
|
||||
|
||||
static cycle_t msm_read_timer_count_shift(struct clocksource *cs)
|
||||
static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs)
|
||||
{
|
||||
/*
|
||||
* Shift timer count down by a constant due to unreliable lower bits
|
||||
|
@ -166,6 +167,11 @@ static struct local_timer_ops msm_local_timer_ops __cpuinitdata = {
|
|||
};
|
||||
#endif /* CONFIG_LOCAL_TIMERS */
|
||||
|
||||
static notrace u32 msm_sched_clock_read(void)
|
||||
{
|
||||
return msm_clocksource.read(&msm_clocksource);
|
||||
}
|
||||
|
||||
static void __init msm_timer_init(void)
|
||||
{
|
||||
struct clock_event_device *ce = &msm_clockevent;
|
||||
|
@ -232,6 +238,8 @@ err:
|
|||
res = clocksource_register_hz(cs, dgt_hz);
|
||||
if (res)
|
||||
pr_err("clocksource_register failed\n");
|
||||
setup_sched_clock(msm_sched_clock_read,
|
||||
cpu_is_msm7x01() ? 32 - MSM_DGT_SHIFT : 32, dgt_hz);
|
||||
}
|
||||
|
||||
struct sys_timer msm_timer = {
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Picochip Ltd., Jamie Iles
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef __MACH_IRQS_H
|
||||
#define __MACH_IRQS_H
|
||||
|
||||
/* We dynamically allocate our irq_desc's. */
|
||||
#define NR_IRQS 0
|
||||
|
||||
#endif /* __MACH_IRQS_H */
|
|
@ -18,6 +18,7 @@
|
|||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <mach/map.h>
|
||||
#include <asm/sched_clock.h>
|
||||
#include <asm/mach/time.h>
|
||||
|
||||
#define SIRFSOC_TIMER_COUNTER_LO 0x0000
|
||||
|
@ -165,21 +166,9 @@ static struct irqaction sirfsoc_timer_irq = {
|
|||
};
|
||||
|
||||
/* Overwrite weak default sched_clock with more precise one */
|
||||
unsigned long long notrace sched_clock(void)
|
||||
static u32 notrace sirfsoc_read_sched_clock(void)
|
||||
{
|
||||
static int is_mapped;
|
||||
|
||||
/*
|
||||
* sched_clock is called earlier than .init of sys_timer
|
||||
* if we map timer memory in .init of sys_timer, system
|
||||
* will panic due to illegal memory access
|
||||
*/
|
||||
if (!is_mapped) {
|
||||
sirfsoc_of_timer_map();
|
||||
is_mapped = 1;
|
||||
}
|
||||
|
||||
return sirfsoc_timer_read(NULL) * (NSEC_PER_SEC / CLOCK_TICK_RATE);
|
||||
return (u32)(sirfsoc_timer_read(NULL) & 0xffffffff);
|
||||
}
|
||||
|
||||
static void __init sirfsoc_clockevent_init(void)
|
||||
|
@ -210,6 +199,8 @@ static void __init sirfsoc_timer_init(void)
|
|||
BUG_ON(rate < CLOCK_TICK_RATE);
|
||||
BUG_ON(rate % CLOCK_TICK_RATE);
|
||||
|
||||
sirfsoc_of_timer_map();
|
||||
|
||||
writel_relaxed(rate / CLOCK_TICK_RATE / 2 - 1, sirfsoc_timer_base + SIRFSOC_TIMER_DIV);
|
||||
writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO);
|
||||
writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI);
|
||||
|
@ -217,6 +208,8 @@ static void __init sirfsoc_timer_init(void)
|
|||
|
||||
BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE));
|
||||
|
||||
setup_sched_clock(sirfsoc_read_sched_clock, 32, CLOCK_TICK_RATE);
|
||||
|
||||
BUG_ON(setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq));
|
||||
|
||||
sirfsoc_clockevent_init();
|
||||
|
|
|
@ -150,6 +150,7 @@ MACHINE_START(CAPC7117,
|
|||
"Embedian CAPC-7117 evaluation kit based on the MXM-8x10 CoM")
|
||||
.atag_offset = 0x100,
|
||||
.map_io = pxa3xx_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa3xx_init_irq,
|
||||
.handle_irq = pxa3xx_handle_irq,
|
||||
.timer = &pxa_timer,
|
||||
|
|
|
@ -854,6 +854,7 @@ static void __init cm_x300_fixup(struct tag *tags, char **cmdline,
|
|||
MACHINE_START(CM_X300, "CM-X300 module")
|
||||
.atag_offset = 0x100,
|
||||
.map_io = pxa3xx_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa3xx_init_irq,
|
||||
.handle_irq = pxa3xx_handle_irq,
|
||||
.timer = &pxa_timer,
|
||||
|
|
|
@ -310,6 +310,7 @@ MACHINE_START(COLIBRI, "Toradex Colibri PXA270")
|
|||
.atag_offset = 0x100,
|
||||
.init_machine = colibri_pxa270_init,
|
||||
.map_io = pxa27x_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa27x_init_irq,
|
||||
.handle_irq = pxa27x_handle_irq,
|
||||
.timer = &pxa_timer,
|
||||
|
@ -320,6 +321,7 @@ MACHINE_START(INCOME, "Income s.r.o. SH-Dmaster PXA270 SBC")
|
|||
.atag_offset = 0x100,
|
||||
.init_machine = colibri_pxa270_income_init,
|
||||
.map_io = pxa27x_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa27x_init_irq,
|
||||
.handle_irq = pxa27x_handle_irq,
|
||||
.timer = &pxa_timer,
|
||||
|
|
|
@ -186,6 +186,7 @@ MACHINE_START(COLIBRI300, "Toradex Colibri PXA300")
|
|||
.atag_offset = 0x100,
|
||||
.init_machine = colibri_pxa300_init,
|
||||
.map_io = pxa3xx_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa3xx_init_irq,
|
||||
.handle_irq = pxa3xx_handle_irq,
|
||||
.timer = &pxa_timer,
|
||||
|
|
|
@ -256,6 +256,7 @@ MACHINE_START(COLIBRI320, "Toradex Colibri PXA320")
|
|||
.atag_offset = 0x100,
|
||||
.init_machine = colibri_pxa320_init,
|
||||
.map_io = pxa3xx_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa3xx_init_irq,
|
||||
.handle_irq = pxa3xx_handle_irq,
|
||||
.timer = &pxa_timer,
|
||||
|
|
|
@ -729,6 +729,7 @@ static void __init fixup_corgi(struct tag *tags, char **cmdline,
|
|||
MACHINE_START(CORGI, "SHARP Corgi")
|
||||
.fixup = fixup_corgi,
|
||||
.map_io = pxa25x_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa25x_init_irq,
|
||||
.handle_irq = pxa25x_handle_irq,
|
||||
.init_machine = corgi_init,
|
||||
|
@ -741,6 +742,7 @@ MACHINE_END
|
|||
MACHINE_START(SHEPHERD, "SHARP Shepherd")
|
||||
.fixup = fixup_corgi,
|
||||
.map_io = pxa25x_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa25x_init_irq,
|
||||
.handle_irq = pxa25x_handle_irq,
|
||||
.init_machine = corgi_init,
|
||||
|
@ -753,6 +755,7 @@ MACHINE_END
|
|||
MACHINE_START(HUSKY, "SHARP Husky")
|
||||
.fixup = fixup_corgi,
|
||||
.map_io = pxa25x_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa25x_init_irq,
|
||||
.handle_irq = pxa25x_handle_irq,
|
||||
.init_machine = corgi_init,
|
||||
|
|
|
@ -274,6 +274,7 @@ static void __init csb726_init(void)
|
|||
MACHINE_START(CSB726, "Cogent CSB726")
|
||||
.atag_offset = 0x100,
|
||||
.map_io = pxa27x_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa27x_init_irq,
|
||||
.handle_irq = pxa27x_handle_irq,
|
||||
.init_machine = csb726_init,
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <mach/pxafb.h>
|
||||
#include <mach/mmc.h>
|
||||
#include <mach/irda.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <mach/ohci.h>
|
||||
#include <plat/pxa27x_keypad.h>
|
||||
#include <mach/camera.h>
|
||||
|
|
|
@ -1301,6 +1301,7 @@ static void __init em_x270_init(void)
|
|||
MACHINE_START(EM_X270, "Compulab EM-X270")
|
||||
.atag_offset = 0x100,
|
||||
.map_io = pxa27x_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa27x_init_irq,
|
||||
.handle_irq = pxa27x_handle_irq,
|
||||
.timer = &pxa_timer,
|
||||
|
@ -1311,6 +1312,7 @@ MACHINE_END
|
|||
MACHINE_START(EXEDA, "Compulab eXeda")
|
||||
.atag_offset = 0x100,
|
||||
.map_io = pxa27x_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa27x_init_irq,
|
||||
.handle_irq = pxa27x_handle_irq,
|
||||
.timer = &pxa_timer,
|
||||
|
|
|
@ -235,6 +235,7 @@ static void __init gumstix_init(void)
|
|||
MACHINE_START(GUMSTIX, "Gumstix")
|
||||
.atag_offset = 0x100, /* match u-boot bi_boot_params */
|
||||
.map_io = pxa25x_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa25x_init_irq,
|
||||
.handle_irq = pxa25x_handle_irq,
|
||||
.timer = &pxa_timer,
|
||||
|
|
|
@ -205,6 +205,7 @@ static void __init h5000_init(void)
|
|||
MACHINE_START(H5400, "HP iPAQ H5000")
|
||||
.atag_offset = 0x100,
|
||||
.map_io = pxa25x_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa25x_init_irq,
|
||||
.handle_irq = pxa25x_handle_irq,
|
||||
.timer = &pxa_timer,
|
||||
|
|
|
@ -160,6 +160,7 @@ static void __init himalaya_init(void)
|
|||
MACHINE_START(HIMALAYA, "HTC Himalaya")
|
||||
.atag_offset = 0x100,
|
||||
.map_io = pxa25x_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa25x_init_irq,
|
||||
.handle_irq = pxa25x_handle_irq,
|
||||
.init_machine = himalaya_init,
|
||||
|
|
|
@ -193,6 +193,7 @@ static void __init icontrol_init(void)
|
|||
MACHINE_START(ICONTROL, "iControl/SafeTcam boards using Embedian MXM-8x10 CoM")
|
||||
.atag_offset = 0x100,
|
||||
.map_io = pxa3xx_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa3xx_init_irq,
|
||||
.handle_irq = pxa3xx_handle_irq,
|
||||
.timer = &pxa_timer,
|
||||
|
|
|
@ -195,6 +195,7 @@ static void __init idp_map_io(void)
|
|||
MACHINE_START(PXA_IDP, "Vibren PXA255 IDP")
|
||||
/* Maintainer: Vibren Technologies */
|
||||
.map_io = idp_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa25x_init_irq,
|
||||
.handle_irq = pxa25x_handle_irq,
|
||||
.timer = &pxa_timer,
|
||||
|
|
|
@ -100,7 +100,7 @@
|
|||
*/
|
||||
#define IRQ_BOARD_START (PXA_GPIO_IRQ_BASE + PXA_NR_BUILTIN_GPIO)
|
||||
|
||||
#define NR_IRQS (IRQ_BOARD_START)
|
||||
#define PXA_NR_IRQS (IRQ_BOARD_START)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
struct irq_data;
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#ifndef ASM_ARCH_MAINSTONE_H
|
||||
#define ASM_ARCH_MAINSTONE_H
|
||||
|
||||
#include <mach/irqs.h>
|
||||
|
||||
#define MST_ETH_PHYS PXA_CS4_PHYS
|
||||
|
||||
#define MST_FPGA_PHYS PXA_CS2_PHYS
|
||||
|
|
|
@ -758,6 +758,7 @@ MACHINE_START(MIOA701, "MIO A701")
|
|||
.atag_offset = 0x100,
|
||||
.restart_mode = 's',
|
||||
.map_io = &pxa27x_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = &pxa27x_init_irq,
|
||||
.handle_irq = &pxa27x_handle_irq,
|
||||
.init_machine = mioa701_machine_init,
|
||||
|
|
|
@ -95,6 +95,7 @@ MACHINE_START(NEC_MP900, "MobilePro900/C")
|
|||
.atag_offset = 0x220100,
|
||||
.timer = &pxa_timer,
|
||||
.map_io = pxa25x_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa25x_init_irq,
|
||||
.handle_irq = pxa25x_handle_irq,
|
||||
.init_machine = mp900c_init,
|
||||
|
|
|
@ -344,6 +344,7 @@ static void __init palmld_init(void)
|
|||
MACHINE_START(PALMLD, "Palm LifeDrive")
|
||||
.atag_offset = 0x100,
|
||||
.map_io = palmld_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa27x_init_irq,
|
||||
.handle_irq = pxa27x_handle_irq,
|
||||
.timer = &pxa_timer,
|
||||
|
|
|
@ -205,6 +205,7 @@ MACHINE_START(PALMT5, "Palm Tungsten|T5")
|
|||
.atag_offset = 0x100,
|
||||
.map_io = pxa27x_map_io,
|
||||
.reserve = palmt5_reserve,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa27x_init_irq,
|
||||
.handle_irq = pxa27x_handle_irq,
|
||||
.timer = &pxa_timer,
|
||||
|
|
|
@ -539,6 +539,7 @@ static void __init palmtc_init(void)
|
|||
MACHINE_START(PALMTC, "Palm Tungsten|C")
|
||||
.atag_offset = 0x100,
|
||||
.map_io = pxa25x_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa25x_init_irq,
|
||||
.handle_irq = pxa25x_handle_irq,
|
||||
.timer = &pxa_timer,
|
||||
|
|
|
@ -358,6 +358,7 @@ static void __init palmte2_init(void)
|
|||
MACHINE_START(PALMTE2, "Palm Tungsten|E2")
|
||||
.atag_offset = 0x100,
|
||||
.map_io = pxa25x_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa25x_init_irq,
|
||||
.handle_irq = pxa25x_handle_irq,
|
||||
.timer = &pxa_timer,
|
||||
|
|
|
@ -448,6 +448,7 @@ MACHINE_START(TREO680, "Palm Treo 680")
|
|||
.atag_offset = 0x100,
|
||||
.map_io = pxa27x_map_io,
|
||||
.reserve = treo_reserve,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa27x_init_irq,
|
||||
.handle_irq = pxa27x_handle_irq,
|
||||
.timer = &pxa_timer,
|
||||
|
@ -461,6 +462,7 @@ MACHINE_START(CENTRO, "Palm Centro 685")
|
|||
.atag_offset = 0x100,
|
||||
.map_io = pxa27x_map_io,
|
||||
.reserve = treo_reserve,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa27x_init_irq,
|
||||
.handle_irq = pxa27x_handle_irq,
|
||||
.timer = &pxa_timer,
|
||||
|
|
|
@ -366,6 +366,7 @@ static void __init palmtx_init(void)
|
|||
MACHINE_START(PALMTX, "Palm T|X")
|
||||
.atag_offset = 0x100,
|
||||
.map_io = palmtx_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa27x_init_irq,
|
||||
.handle_irq = pxa27x_handle_irq,
|
||||
.timer = &pxa_timer,
|
||||
|
|
|
@ -401,6 +401,7 @@ static void __init palmz72_init(void)
|
|||
MACHINE_START(PALMZ72, "Palm Zire72")
|
||||
.atag_offset = 0x100,
|
||||
.map_io = pxa27x_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa27x_init_irq,
|
||||
.handle_irq = pxa27x_handle_irq,
|
||||
.timer = &pxa_timer,
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <mach/pm.h>
|
||||
#include <mach/dma.h>
|
||||
#include <mach/smemc.h>
|
||||
#include <mach/irqs.h>
|
||||
|
||||
#include "generic.h"
|
||||
#include "devices.h"
|
||||
|
|
|
@ -1090,6 +1090,7 @@ MACHINE_START(RAUMFELD_RC, "Raumfeld Controller")
|
|||
.atag_offset = 0x100,
|
||||
.init_machine = raumfeld_controller_init,
|
||||
.map_io = pxa3xx_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa3xx_init_irq,
|
||||
.handle_irq = pxa3xx_handle_irq,
|
||||
.timer = &pxa_timer,
|
||||
|
@ -1102,6 +1103,7 @@ MACHINE_START(RAUMFELD_CONNECTOR, "Raumfeld Connector")
|
|||
.atag_offset = 0x100,
|
||||
.init_machine = raumfeld_connector_init,
|
||||
.map_io = pxa3xx_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa3xx_init_irq,
|
||||
.handle_irq = pxa3xx_handle_irq,
|
||||
.timer = &pxa_timer,
|
||||
|
@ -1114,6 +1116,7 @@ MACHINE_START(RAUMFELD_SPEAKER, "Raumfeld Speaker")
|
|||
.atag_offset = 0x100,
|
||||
.init_machine = raumfeld_speaker_init,
|
||||
.map_io = pxa3xx_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa3xx_init_irq,
|
||||
.handle_irq = pxa3xx_handle_irq,
|
||||
.timer = &pxa_timer,
|
||||
|
|
|
@ -598,6 +598,7 @@ MACHINE_START(SAAR, "PXA930 Handheld Platform (aka SAAR)")
|
|||
/* Maintainer: Eric Miao <eric.miao@marvell.com> */
|
||||
.atag_offset = 0x100,
|
||||
.map_io = pxa3xx_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa3xx_init_irq,
|
||||
.handle_irq = pxa3xx_handle_irq,
|
||||
.timer = &pxa_timer,
|
||||
|
|
|
@ -984,6 +984,7 @@ MACHINE_START(SPITZ, "SHARP Spitz")
|
|||
.restart_mode = 'g',
|
||||
.fixup = spitz_fixup,
|
||||
.map_io = pxa27x_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa27x_init_irq,
|
||||
.handle_irq = pxa27x_handle_irq,
|
||||
.init_machine = spitz_init,
|
||||
|
@ -997,6 +998,7 @@ MACHINE_START(BORZOI, "SHARP Borzoi")
|
|||
.restart_mode = 'g',
|
||||
.fixup = spitz_fixup,
|
||||
.map_io = pxa27x_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa27x_init_irq,
|
||||
.handle_irq = pxa27x_handle_irq,
|
||||
.init_machine = spitz_init,
|
||||
|
@ -1010,6 +1012,7 @@ MACHINE_START(AKITA, "SHARP Akita")
|
|||
.restart_mode = 'g',
|
||||
.fixup = spitz_fixup,
|
||||
.map_io = pxa27x_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa27x_init_irq,
|
||||
.handle_irq = pxa27x_handle_irq,
|
||||
.init_machine = spitz_init,
|
||||
|
|
|
@ -1006,6 +1006,7 @@ static void __init stargate2_init(void)
|
|||
#ifdef CONFIG_MACH_INTELMOTE2
|
||||
MACHINE_START(INTELMOTE2, "IMOTE 2")
|
||||
.map_io = pxa27x_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa27x_init_irq,
|
||||
.handle_irq = pxa27x_handle_irq,
|
||||
.timer = &pxa_timer,
|
||||
|
|
|
@ -491,6 +491,7 @@ MACHINE_START(TAVOREVB, "PXA930 Evaluation Board (aka TavorEVB)")
|
|||
/* Maintainer: Eric Miao <eric.miao@marvell.com> */
|
||||
.atag_offset = 0x100,
|
||||
.map_io = pxa3xx_map_io,
|
||||
.nr_irqs = PXA_NR_IRQS,
|
||||
.init_irq = pxa3xx_init_irq,
|
||||
.handle_irq = pxa3xx_handle_irq,
|
||||
.timer = &pxa_timer,
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <asm/mach/time.h>
|
||||
#include <asm/sched_clock.h>
|
||||
#include <mach/regs-ost.h>
|
||||
#include <mach/irqs.h>
|
||||
|
||||
/*
|
||||
* This is PXA's sched_clock implementation. This has a resolution
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue