VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 36
- - -- EXTRAVERSION = -rc3
- EXTRAVERSION = -rc4
- - -EXTRAVERSION = -rc2
++++ ++++EXTRAVERSION = -rc6
NAME = Sheep on Meth
# *DOCUMENTATION*
ifdef CONFIG_FRAME_POINTER
KBUILD_CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls
else
++ ++++++# Some targets (ARM with Thumb2, for example), can't be built with frame
++ ++++++# pointers. For those, we don't have FUNCTION_TRACER automatically
++ ++++++# select FRAME_POINTER. However, FUNCTION_TRACER adds -pg, and this is
++ ++++++# incompatible with -fomit-frame-pointer with current GCC, so we don't use
++ ++++++# -fomit-frame-pointer with FUNCTION_TRACER.
++ ++++++ifndef CONFIG_FUNCTION_TRACER
KBUILD_CFLAGS += -fomit-frame-pointer
endif
++ ++++++endif
ifdef CONFIG_DEBUG_INFO
KBUILD_CFLAGS += -g
select HAVE_KPROBES if (!XIP_KERNEL)
select HAVE_KRETPROBES if (HAVE_KPROBES)
select HAVE_FUNCTION_TRACER if (!XIP_KERNEL)
++ ++++++ select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL)
++ ++++++ select HAVE_DYNAMIC_FTRACE if (!XIP_KERNEL)
select HAVE_GENERIC_DMA_COHERENT
select HAVE_KERNEL_GZIP
select HAVE_KERNEL_LZO
select HAVE_PERF_EVENTS
select PERF_USE_VMALLOC
select HAVE_REGS_AND_STACK_ACCESS_API
+++ +++++ select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V7))
help
The ARM series is a line of low-power-consumption RISC chip designs
licensed by ARM Ltd and targeted at embedded applications and
and that the relevant menu configurations are displayed for
it.
++++ ++++config ARCH_HAS_CPU_IDLE_WAIT
++++ ++++ def_bool y
++++ ++++
config GENERIC_HWEIGHT
bool
default y
bool "Atmel AT91"
select ARCH_REQUIRE_GPIOLIB
select HAVE_CLK
---- ---- select ARCH_USES_GETTIMEOFFSET
help
This enables support for systems based on the Atmel AT91RM9200,
AT91SAM9 and AT91CAP9 processors.
config ARM_ERRATA_411920
bool "ARM errata: Invalidation of the Instruction Cache operation can fail"
---- ---- depends on CPU_V6 && !SMP
++++ ++++ depends on CPU_V6
help
Invalidation of the Instruction Cache operation can
fail. This erratum is present in 1136 (before r1p4), 1156 and 1176.
ACTLR register. Note that setting specific bits in the ACTLR register
may not be available in non-secure mode.
++++ ++++config ARM_ERRATA_742230
++++ ++++ bool "ARM errata: DMB operation may be faulty"
++++ ++++ depends on CPU_V7 && SMP
++++ ++++ help
++++ ++++ This option enables the workaround for the 742230 Cortex-A9
++++ ++++ (r1p0..r2p2) erratum. Under rare circumstances, a DMB instruction
++++ ++++ between two write operations may not ensure the correct visibility
++++ ++++ ordering of the two writes. This workaround sets a specific bit in
++++ ++++ the diagnostic register of the Cortex-A9 which causes the DMB
++++ ++++ instruction to behave as a DSB, ensuring the correct behaviour of
++++ ++++ the two writes.
++++ ++++
++++ ++++config ARM_ERRATA_742231
++++ ++++ bool "ARM errata: Incorrect hazard handling in the SCU may lead to data corruption"
++++ ++++ depends on CPU_V7 && SMP
++++ ++++ help
++++ ++++ This option enables the workaround for the 742231 Cortex-A9
++++ ++++ (r2p0..r2p2) erratum. Under certain conditions, specific to the
++++ ++++ Cortex-A9 MPCore micro-architecture, two CPUs working in SMP mode,
++++ ++++ accessing some data located in the same cache line, may get corrupted
++++ ++++ data due to bad handling of the address hazard when the line gets
++++ ++++ replaced from one of the CPUs at the same time as another CPU is
++++ ++++ accessing it. This workaround sets specific bits in the diagnostic
++++ ++++ register of the Cortex-A9 which reduces the linefill issuing
++++ ++++ capabilities of the processor.
++++ ++++
config PL310_ERRATA_588369
bool "Clean & Invalidate maintenance operations do not invalidate clean lines"
depends on CACHE_L2X0 && ARCH_OMAP4
config SMP
bool "Symmetric Multi-Processing (EXPERIMENTAL)"
---- ---- depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP ||\
---- ---- MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 ||\
---- ---- ARCH_S5PV310 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4)
++++ ++++ depends on EXPERIMENTAL
depends on GENERIC_CLOCKEVENTS
++++ ++++ depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \
++++ ++++ MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 ||\
++++ ++++ ARCH_S5PV310 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4
select USE_GENERIC_SMP_HELPERS
---- ---- select HAVE_ARM_SCU if ARCH_REALVIEW || ARCH_OMAP4 || ARCH_S5PV310 ||\
---- ---- ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4
++++ ++++ select HAVE_ARM_SCU
help
This enables support for systems with more than one CPU. If you have
a system with only one CPU, like most personal computers, say N. If
If you don't know what to do here, say N.
++++ ++++config SMP_ON_UP
++++ ++++ bool "Allow booting SMP kernel on uniprocessor systems (EXPERIMENTAL)"
++++ ++++ depends on EXPERIMENTAL
++++ ++++ depends on SMP && !XIP && !THUMB2_KERNEL
++++ ++++ default y
++++ ++++ help
++++ ++++ SMP kernels contain instructions which fail on non-SMP processors.
++++ ++++ Enabling this option allows the kernel to modify itself to make
++++ ++++ these instructions safe. Disabling it allows about 1K of space
++++ ++++ savings.
++++ ++++
++++ ++++ If you don't know what to do here, say Y.
++++ ++++
config HAVE_ARM_SCU
bool
depends on SMP
config LOCAL_TIMERS
bool "Use local timer interrupts"
---- ---- depends on SMP && (REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || \
---- ---- REALVIEW_EB_A9MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
---- ---- ARCH_S5PV310 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4)
++++ ++++ depends on SMP
default y
---- ---- select HAVE_ARM_TWD if ARCH_REALVIEW || ARCH_OMAP4 || ARCH_S5PV310 || \
---- ---- ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS
++++ ++++ select HAVE_ARM_TWD
help
Enable support for local timers on SMP platforms, rather then the
legacy IPI broadcast method. Local timers allows the system
0xf8000000. This assumes the zImage being placed in the first 128MB
from start of memory.
- -- ----config ZRELADDR
- -- ---- hex "Physical address of the decompressed kernel image"
- -- ---- depends on !AUTO_ZRELADDR
- -- ---- default 0x00008000 if ARCH_BCMRING ||\
- -- ---- ARCH_CNS3XXX ||\
- -- ---- ARCH_DOVE ||\
- -- ---- ARCH_EBSA110 ||\
- -- ---- ARCH_FOOTBRIDGE ||\
- -- ---- ARCH_INTEGRATOR ||\
- -- ---- ARCH_IOP13XX ||\
- -- ---- ARCH_IOP33X ||\
- -- ---- ARCH_IXP2000 ||\
- -- ---- ARCH_IXP23XX ||\
- -- ---- ARCH_IXP4XX ||\
- -- ---- ARCH_KIRKWOOD ||\
- -- ---- ARCH_KS8695 ||\
- -- ---- ARCH_LOKI ||\
- -- ---- ARCH_MMP ||\
- -- ---- ARCH_MV78XX0 ||\
- -- ---- ARCH_NOMADIK ||\
- -- ---- ARCH_NUC93X ||\
- -- ---- ARCH_NS9XXX ||\
- -- ---- ARCH_ORION5X ||\
- -- ---- ARCH_SPEAR3XX ||\
- -- ---- ARCH_SPEAR6XX ||\
- ARCH_TEGRA ||\
- -- ---- ARCH_U8500 ||\
- -- ---- ARCH_VERSATILE ||\
- -- ---- ARCH_W90X900
- -- ---- default 0x08008000 if ARCH_MX1 ||\
- -- ---- ARCH_SHARK
- -- ---- default 0x10008000 if ARCH_MSM ||\
- -- ---- ARCH_OMAP1 ||\
- -- ---- ARCH_RPC
- -- ---- default 0x20008000 if ARCH_S5P6440 ||\
- -- ---- ARCH_S5P6442 ||\
- -- ---- ARCH_S5PC100 ||\
- -- ---- ARCH_S5PV210
- -- ---- default 0x30008000 if ARCH_S3C2410 ||\
- -- ---- ARCH_S3C2400 ||\
- -- ---- ARCH_S3C2412 ||\
- -- ---- ARCH_S3C2416 ||\
- -- ---- ARCH_S3C2440 ||\
- -- ---- ARCH_S3C2443
- -- ---- default 0x40008000 if ARCH_STMP378X ||\
- -- ---- ARCH_STMP37XX ||\
- -- ---- ARCH_SH7372 ||\
- - -- ARCH_SH7377 ||\
- - -- ARCH_S5PV310
- - - ARCH_SH7377
- -- ---- default 0x50008000 if ARCH_S3C64XX ||\
- -- ---- ARCH_SH7367
- -- ---- default 0x60008000 if ARCH_VEXPRESS
- -- ---- default 0x80008000 if ARCH_MX25 ||\
- -- ---- ARCH_MX3 ||\
- -- ---- ARCH_NETX ||\
- -- ---- ARCH_OMAP2PLUS ||\
- -- ---- ARCH_PNX4008
- -- ---- default 0x90008000 if ARCH_MX5 ||\
- -- ---- ARCH_MX91231
- -- ---- default 0xa0008000 if ARCH_IOP32X ||\
- -- ---- ARCH_PXA ||\
- -- ---- MACH_MX27
- -- ---- default 0xc0008000 if ARCH_LH7A40X ||\
- -- ---- MACH_MX21
- -- ---- default 0xf0008000 if ARCH_AAEC2000 ||\
- -- ---- ARCH_L7200
- -- ---- default 0xc0028000 if ARCH_CLPS711X
- -- ---- default 0x70008000 if ARCH_AT91 && (ARCH_AT91CAP9 || ARCH_AT91SAM9G45)
- -- ---- default 0x20008000 if ARCH_AT91 && !(ARCH_AT91CAP9 || ARCH_AT91SAM9G45)
- -- ---- default 0xc0008000 if ARCH_DAVINCI && ARCH_DAVINCI_DA8XX
- -- ---- default 0x80008000 if ARCH_DAVINCI && !ARCH_DAVINCI_DA8XX
- -- ---- default 0x00008000 if ARCH_EP93XX && EP93XX_SDCE3_SYNC_PHYS_OFFSET
- -- ---- default 0xc0008000 if ARCH_EP93XX && EP93XX_SDCE0_PHYS_OFFSET
- -- ---- default 0xd0008000 if ARCH_EP93XX && EP93XX_SDCE1_PHYS_OFFSET
- -- ---- default 0xe0008000 if ARCH_EP93XX && EP93XX_SDCE2_PHYS_OFFSET
- -- ---- default 0xf0008000 if ARCH_EP93XX && EP93XX_SDCE3_ASYNC_PHYS_OFFSET
- -- ---- default 0x00008000 if ARCH_GEMINI && GEMINI_MEM_SWAP
- -- ---- default 0x10008000 if ARCH_GEMINI && !GEMINI_MEM_SWAP
- -- ---- default 0x70008000 if ARCH_REALVIEW && REALVIEW_HIGH_PHYS_OFFSET
- -- ---- default 0x00008000 if ARCH_REALVIEW && !REALVIEW_HIGH_PHYS_OFFSET
- -- ---- default 0xc0208000 if ARCH_SA1100 && SA1111
- -- ---- default 0xc0008000 if ARCH_SA1100 && !SA1111
- -- ---- default 0x30108000 if ARCH_S3C2410 && PM_H1940
- -- ---- default 0x28E08000 if ARCH_U300 && MACH_U300_SINGLE_RAM
- -- ---- default 0x48008000 if ARCH_U300 && !MACH_U300_SINGLE_RAM
- -- ---- help
- -- ---- ZRELADDR is the physical address where the decompressed kernel
- -- ---- image will be placed. ZRELADDR has to be specified when the
- -- ---- assumption of AUTO_ZRELADDR is not valid, or when ZBOOT_ROM is
- -- ---- selected.
- -- ----
endmenu
menu "CPU Power Management"
#endif
/*
- ------- * This flag is used to indicate that the page pointed to by a pte
- ------- * is dirty and requires cleaning before returning it to the user.
+ +++++++ * This flag is used to indicate that the page pointed to by a pte is clean
+ +++++++ * and does not require cleaning before returning it to the user.
*/
- -------#define PG_dcache_dirty PG_arch_1
+ +++++++#define PG_dcache_clean PG_arch_1
/*
* MM Cache Management
* Please note that the implementation of these, and the required
* effects are cache-type (VIVT/VIPT/PIPT) specific.
*
++++ ++++ * flush_icache_all()
++++ ++++ *
++++ ++++ * Unconditionally clean and invalidate the entire icache.
++++ ++++ * Currently only needed for cache-v6.S and cache-v7.S, see
++++ ++++ * __flush_icache_all for the generic implementation.
++++ ++++ *
* flush_kern_all()
*
* Unconditionally clean and invalidate the entire cache.
*/
struct cpu_cache_fns {
++++ ++++ void (*flush_icache_all)(void);
void (*flush_kern_all)(void);
void (*flush_user_all)(void);
void (*flush_user_range)(unsigned long, unsigned long, unsigned int);
extern struct cpu_cache_fns cpu_cache;
++++ ++++#define __cpuc_flush_icache_all cpu_cache.flush_icache_all
#define __cpuc_flush_kern_all cpu_cache.flush_kern_all
#define __cpuc_flush_user_all cpu_cache.flush_user_all
#define __cpuc_flush_user_range cpu_cache.flush_user_range
#else
++++ ++++#define __cpuc_flush_icache_all __glue(_CACHE,_flush_icache_all)
#define __cpuc_flush_kern_all __glue(_CACHE,_flush_kern_cache_all)
#define __cpuc_flush_user_all __glue(_CACHE,_flush_user_cache_all)
#define __cpuc_flush_user_range __glue(_CACHE,_flush_user_cache_range)
#define __cpuc_coherent_user_range __glue(_CACHE,_coherent_user_range)
#define __cpuc_flush_dcache_area __glue(_CACHE,_flush_kern_dcache_area)
++++ ++++extern void __cpuc_flush_icache_all(void);
extern void __cpuc_flush_kern_all(void);
extern void __cpuc_flush_user_all(void);
extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int);
/*
* Convert calls to our calling convention.
*/
++++ ++++
++++ ++++/* Invalidate I-cache */
++++ ++++#define __flush_icache_all_generic() \
++++ ++++ asm("mcr p15, 0, %0, c7, c5, 0" \
++++ ++++ : : "r" (0));
++++ ++++
++++ ++++/* Invalidate I-cache inner shareable */
++++ ++++#define __flush_icache_all_v7_smp() \
++++ ++++ asm("mcr p15, 0, %0, c7, c1, 0" \
++++ ++++ : : "r" (0));
++++ ++++
++++ ++++/*
++++ ++++ * Optimized __flush_icache_all for the common cases. Note that UP ARMv7
++++ ++++ * will fall through to use __flush_icache_all_generic.
++++ ++++ */
++++ ++++#if (defined(CONFIG_CPU_V7) && defined(CONFIG_CPU_V6)) || \
++++ ++++ defined(CONFIG_SMP_ON_UP)
++++ ++++#define __flush_icache_preferred __cpuc_flush_icache_all
++++ ++++#elif __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)
++++ ++++#define __flush_icache_preferred __flush_icache_all_v7_smp
++++ ++++#elif __LINUX_ARM_ARCH__ == 6 && defined(CONFIG_ARM_ERRATA_411920)
++++ ++++#define __flush_icache_preferred __cpuc_flush_icache_all
++++ ++++#else
++++ ++++#define __flush_icache_preferred __flush_icache_all_generic
++++ ++++#endif
++++ ++++
++++ ++++static inline void __flush_icache_all(void)
++++ ++++{
++++ ++++ __flush_icache_preferred();
++++ ++++}
++++ ++++
#define flush_cache_all() __cpuc_flush_kern_all()
static inline void vivt_flush_cache_mm(struct mm_struct *mm)
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
extern void flush_dcache_page(struct page *);
---- ----static inline void __flush_icache_all(void)
---- ----{
---- ----#ifdef CONFIG_ARM_ERRATA_411920
---- ---- extern void v6_icache_inval_all(void);
---- ---- v6_icache_inval_all();
---- ----#elif defined(CONFIG_SMP) && __LINUX_ARM_ARCH__ >= 7
---- ---- asm("mcr p15, 0, %0, c7, c1, 0 @ invalidate I-cache inner shareable\n"
---- ---- :
---- ---- : "r" (0));
---- ----#else
---- ---- asm("mcr p15, 0, %0, c7, c5, 0 @ invalidate I-cache\n"
---- ---- :
---- ---- : "r" (0));
---- ----#endif
---- ----}
static inline void flush_kernel_vmap_range(void *addr, int size)
{
if ((cache_is_vivt() || cache_is_vipt_aliasing()))
#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
static inline void flush_kernel_dcache_page(struct page *page)
{
- ------- /* highmem pages are always flushed upon kunmap already */
- ------- if ((cache_is_vivt() || cache_is_vipt_aliasing()) && !PageHighMem(page))
- ------- __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE);
}
#define flush_dcache_mmap_lock(mapping) \
#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
- -------#define set_pte_at(mm,addr,ptep,pteval) do { \
- ------- set_pte_ext(ptep, pteval, (addr) >= TASK_SIZE ? 0 : PTE_EXT_NG); \
- ------- } while (0)
+ +++++++#if __LINUX_ARM_ARCH__ < 6
+ +++++++static inline void __sync_icache_dcache(pte_t pteval)
+ +++++++{
+ +++++++}
+ +++++++#else
+ +++++++extern void __sync_icache_dcache(pte_t pteval);
+ +++++++#endif
+ +++++++
+ +++++++static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
+ +++++++ pte_t *ptep, pte_t pteval)
+ +++++++{
+ +++++++ if (addr >= TASK_SIZE)
+ +++++++ set_pte_ext(ptep, pteval, 0);
+ +++++++ else {
+ +++++++ __sync_icache_dcache(pteval);
+ +++++++ set_pte_ext(ptep, pteval, PTE_EXT_NG);
+ +++++++ }
+ +++++++}
/*
* The following only work if pte_present() is true.
#define pte_write(pte) (pte_val(pte) & L_PTE_WRITE)
#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY)
#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG)
+ +++++++#define pte_exec(pte) (pte_val(pte) & L_PTE_EXEC)
#define pte_special(pte) (0)
+ +++++++#define pte_present_user(pte) \
+ +++++++ ((pte_val(pte) & (L_PTE_PRESENT | L_PTE_USER)) == \
+ +++++++ (L_PTE_PRESENT | L_PTE_USER))
+ +++++++
#define PTE_BIT_FUNC(fn,op) \
static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
#define pgprot_dmacoherent(prot) \
__pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_BUFFERABLE)
++++ ++++#define __HAVE_PHYS_MEM_ACCESS_PROT
++++ ++++struct file;
++++ ++++extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
++++ ++++ unsigned long size, pgprot_t vma_prot);
#else
#define pgprot_dmacoherent(prot) \
__pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_UNCACHED)
#include <asm/cputype.h>
++++ ++++/*
++++ ++++ * Return true if we are running on a SMP platform
++++ ++++ */
++++ ++++static inline bool is_smp(void)
++++ ++++{
++++ ++++#ifndef CONFIG_SMP
++++ ++++ return false;
++++ ++++#elif defined(CONFIG_SMP_ON_UP)
++++ ++++ extern unsigned int smp_on_up;
++++ ++++ return !!smp_on_up;
++++ ++++#else
++++ ++++ return true;
++++ ++++#endif
++++ ++++}
++++ ++++
/* all SMP configurations have the extended CPUID registers */
static inline int tlb_ops_need_broadcast(void)
{
++++ ++++ if (!is_smp())
++++ ++++ return 0;
++++ ++++
return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2;
}
+ +++++++#if !defined(CONFIG_SMP) || __LINUX_ARM_ARCH__ >= 7
+ +++++++#define cache_ops_need_broadcast() 0
+ +++++++#else
static inline int cache_ops_need_broadcast(void)
{
++++ ++++ if (!is_smp())
++++ ++++ return 0;
++++ ++++
return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 1;
}
+ +++++++#endif
#endif
struct pt_regs *),
int sig, int code, const char *name);
+++ +++++void hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int,
+++ +++++ struct pt_regs *),
+++ +++++ int sig, int code, const char *name);
+++ +++++
#define xchg(ptr,x) \
((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
extern void disable_hlt(void);
extern void enable_hlt(void);
++++ ++++void cpu_idle_wait(void);
++++ ++++
#include <asm-generic/cmpxchg-local.h>
#if __LINUX_ARM_ARCH__ < 6
#undef _TLB
#undef MULTI_TLB
++++ ++++#ifdef CONFIG_SMP_ON_UP
++++ ++++#define MULTI_TLB 1
++++ ++++#endif
++++ ++++
#define v3_tlb_flags (TLB_V3_FULL | TLB_V3_PAGE)
#ifdef CONFIG_CPU_TLB_V3
# define v6wbi_always_flags (-1UL)
#endif
---- ----#ifdef CONFIG_SMP
---- ----#define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_V7_IS_BTB | \
++++ ++++#define v7wbi_tlb_flags_smp (TLB_WB | TLB_DCLEAN | TLB_V7_IS_BTB | \
TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | TLB_V7_UIS_ASID)
---- ----#else
---- ----#define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BTB | \
++++ ++++#define v7wbi_tlb_flags_up (TLB_WB | TLB_DCLEAN | TLB_BTB | \
TLB_V6_U_FULL | TLB_V6_U_PAGE | TLB_V6_U_ASID)
---- ----#endif
#ifdef CONFIG_CPU_TLB_V7
---- ----# define v7wbi_possible_flags v7wbi_tlb_flags
---- ----# define v7wbi_always_flags v7wbi_tlb_flags
++++ ++++
++++ ++++# ifdef CONFIG_SMP_ON_UP
++++ ++++# define v7wbi_possible_flags (v7wbi_tlb_flags_smp | v7wbi_tlb_flags_up)
++++ ++++# define v7wbi_always_flags (v7wbi_tlb_flags_smp & v7wbi_tlb_flags_up)
++++ ++++# elif defined(CONFIG_SMP)
++++ ++++# define v7wbi_possible_flags v7wbi_tlb_flags_smp
++++ ++++# define v7wbi_always_flags v7wbi_tlb_flags_smp
++++ ++++# else
++++ ++++# define v7wbi_possible_flags v7wbi_tlb_flags_up
++++ ++++# define v7wbi_always_flags v7wbi_tlb_flags_up
++++ ++++# endif
# ifdef _TLB
# define MULTI_TLB 1
# else
#endif
/*
- ------- * if PG_dcache_dirty is set for the page, we need to ensure that any
+ +++++++ * If PG_dcache_clean is not set for the page, we need to ensure that any
* cache entries for the kernels virtual memory range are written
- ------- * back to the page.
+ +++++++ * back to the page. On ARMv6 and later, the cache coherency is handled via
+ +++++++ * the set_pte_at() function.
*/
+ +++++++#if __LINUX_ARM_ARCH__ < 6
extern void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
pte_t *ptep);
+ +++++++#else
+ +++++++static inline void update_mmu_cache(struct vm_area_struct *vma,
+ +++++++ unsigned long addr, pte_t *ptep)
+ +++++++{
+ +++++++}
+ +++++++#endif
#endif
beq no_work_pending
mov r0, sp @ 'regs'
mov r2, why @ 'syscall'
++++ ++++ tst r1, #_TIF_SIGPENDING @ delivering a signal?
++++ ++++ movne why, #0 @ prevent further restarts
bl do_notify_resume
b ret_slow_syscall @ Check work again
* clobber the ip register. This is OK because the ARM calling convention
* allows it to be clobbered in subroutines and doesn't use it to hold
* parameters.)
++ ++++++ *
++ ++++++ * When using dynamic ftrace, we patch out the mcount call by a "mov r0, r0"
++ ++++++ * for the mcount case, and a "pop {lr}" for the __gnu_mcount_nc case (see
++ ++++++ * arch/arm/kernel/ftrace.c).
*/
++ ++++++
++ ++++++#ifndef CONFIG_OLD_MCOUNT
++ ++++++#if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4))
++ ++++++#error Ftrace requires CONFIG_FRAME_POINTER=y with GCC older than 4.4.0.
++ ++++++#endif
++ ++++++#endif
++ ++++++
#ifdef CONFIG_DYNAMIC_FTRACE
-- ------ENTRY(mcount)
++ ++++++ENTRY(__gnu_mcount_nc)
++ ++++++ mov ip, lr
++ ++++++ ldmia sp!, {lr}
++ ++++++ mov pc, ip
++ ++++++ENDPROC(__gnu_mcount_nc)
++ ++++++
++ ++++++ENTRY(ftrace_caller)
stmdb sp!, {r0-r3, lr}
mov r0, lr
sub r0, r0, #MCOUNT_INSN_SIZE
++ ++++++ ldr r1, [sp, #20]
-- ------ .globl mcount_call
-- ------mcount_call:
++ ++++++ .global ftrace_call
++ ++++++ftrace_call:
bl ftrace_stub
-- ------ ldr lr, [fp, #-4] @ restore lr
-- ------ ldmia sp!, {r0-r3, pc}
++ ++++++ ldmia sp!, {r0-r3, ip, lr}
++ ++++++ mov pc, ip
++ ++++++ENDPROC(ftrace_caller)
-- ------ENTRY(ftrace_caller)
++ ++++++#ifdef CONFIG_OLD_MCOUNT
++ ++++++ENTRY(mcount)
++ ++++++ stmdb sp!, {lr}
++ ++++++ ldr lr, [fp, #-4]
++ ++++++ ldmia sp!, {pc}
++ ++++++ENDPROC(mcount)
++ ++++++
++ ++++++ENTRY(ftrace_caller_old)
stmdb sp!, {r0-r3, lr}
ldr r1, [fp, #-4]
mov r0, lr
sub r0, r0, #MCOUNT_INSN_SIZE
-- ------ .globl ftrace_call
-- ------ftrace_call:
++ ++++++ .globl ftrace_call_old
++ ++++++ftrace_call_old:
bl ftrace_stub
ldr lr, [fp, #-4] @ restore lr
ldmia sp!, {r0-r3, pc}
++ ++++++ENDPROC(ftrace_caller_old)
++ ++++++#endif
#else
stmdb sp!, {r0-r3, lr}
ldr r0, =ftrace_trace_function
ldr r2, [r0]
-- ------ adr r0, ftrace_stub
++ ++++++ adr r0, .Lftrace_stub
cmp r0, r2
bne gnu_trace
ldmia sp!, {r0-r3, ip, lr}
ldr r1, [sp, #20] @ lr of instrumented routine
mov r0, lr
sub r0, r0, #MCOUNT_INSN_SIZE
-- ------ mov lr, pc
++ ++++++ adr lr, BSYM(1f)
mov pc, r2
++ ++++++1:
ldmia sp!, {r0-r3, ip, lr}
mov pc, ip
++ ++++++ENDPROC(__gnu_mcount_nc)
++ ++++++#ifdef CONFIG_OLD_MCOUNT
++ ++++++/*
++ ++++++ * This is under an ifdef in order to force link-time errors for people trying
++ ++++++ * to build with !FRAME_POINTER with a GCC which doesn't use the new-style
++ ++++++ * mcount.
++ ++++++ */
ENTRY(mcount)
stmdb sp!, {r0-r3, lr}
ldr r0, =ftrace_trace_function
mov pc, r2
ldr lr, [fp, #-4] @ restore lr
ldmia sp!, {r0-r3, pc}
++ ++++++ENDPROC(mcount)
++ ++++++#endif
#endif /* CONFIG_DYNAMIC_FTRACE */
-- ------ .globl ftrace_stub
-- ------ftrace_stub:
++ ++++++ENTRY(ftrace_stub)
++ ++++++.Lftrace_stub:
mov pc, lr
++ ++++++ENDPROC(ftrace_stub)
#endif /* CONFIG_FUNCTION_TRACER */
sys_sigreturn_wrapper:
add r0, sp, #S_OFF
+ ++ ++++ mov why, #0 @ prevent syscall restart handling
b sys_sigreturn
ENDPROC(sys_sigreturn_wrapper)
sys_rt_sigreturn_wrapper:
add r0, sp, #S_OFF
+ ++ ++++ mov why, #0 @ prevent syscall restart handling
b sys_rt_sigreturn
ENDPROC(sys_rt_sigreturn_wrapper)
#include <linux/utsname.h>
#include <linux/uaccess.h>
#include <linux/random.h>
+++ +++++#include <linux/hw_breakpoint.h>
#include <asm/cacheflush.h>
#include <asm/leds.h>
void (*arm_pm_restart)(char str, const char *cmd) = arm_machine_restart;
EXPORT_SYMBOL_GPL(arm_pm_restart);
++++ ++++static void do_nothing(void *unused)
++++ ++++{
++++ ++++}
++++ ++++
++++ ++++/*
++++ ++++ * cpu_idle_wait - Used to ensure that all the CPUs discard old value of
++++ ++++ * pm_idle and update to new pm_idle value. Required while changing pm_idle
++++ ++++ * handler on SMP systems.
++++ ++++ *
++++ ++++ * Caller must have changed pm_idle to the new value before the call. Old
++++ ++++ * pm_idle value will not be used by any CPU after the return of this function.
++++ ++++ */
++++ ++++void cpu_idle_wait(void)
++++ ++++{
++++ ++++ smp_mb();
++++ ++++ /* kick all the CPUs so that they exit out of pm_idle */
++++ ++++ smp_call_function(do_nothing, NULL, 1);
++++ ++++}
++++ ++++EXPORT_SYMBOL_GPL(cpu_idle_wait);
/*
* This is our default idle handler. We need to disable
struct thread_info *thread = current_thread_info();
struct task_struct *tsk = current;
+++ +++++ flush_ptrace_hw_breakpoint(tsk);
+++ +++++
memset(thread->used_cp, 0, sizeof(thread->used_cp));
memset(&tsk->thread.debug, 0, sizeof(struct debug_info));
memset(&thread->fpstate, 0, sizeof(union fp_state));
thread->cpu_context.sp = (unsigned long)childregs;
thread->cpu_context.pc = (unsigned long)ret_from_fork;
+++ +++++ clear_ptrace_hw_breakpoint(p);
+++ +++++
if (clone_flags & CLONE_SETTLS)
thread->tp_value = regs->ARM_r3;
#include <asm/procinfo.h>
#include <asm/sections.h>
#include <asm/setup.h>
++++ ++++#include <asm/smp_plat.h>
#include <asm/mach-types.h>
#include <asm/cacheflush.h>
#include <asm/cachetype.h>
return cpu_arch;
}
+ +++++++static int cpu_has_aliasing_icache(unsigned int arch)
+ +++++++{
+ +++++++ int aliasing_icache;
+ +++++++ unsigned int id_reg, num_sets, line_size;
+ +++++++
+ +++++++ /* arch specifies the register format */
+ +++++++ switch (arch) {
+ +++++++ case CPU_ARCH_ARMv7:
+ +++++++ asm("mcr p15, 2, %0, c0, c0, 0 @ set CSSELR"
+ +++++++ : /* No output operands */
+ +++++++ : "r" (1));
+ +++++++ isb();
+ +++++++ asm("mrc p15, 1, %0, c0, c0, 0 @ read CCSIDR"
+ +++++++ : "=r" (id_reg));
+ +++++++ line_size = 4 << ((id_reg & 0x7) + 2);
+ +++++++ num_sets = ((id_reg >> 13) & 0x7fff) + 1;
+ +++++++ aliasing_icache = (line_size * num_sets) > PAGE_SIZE;
+ +++++++ break;
+ +++++++ case CPU_ARCH_ARMv6:
+ +++++++ aliasing_icache = read_cpuid_cachetype() & (1 << 11);
+ +++++++ break;
+ +++++++ default:
+ +++++++ /* I-cache aliases will be handled by D-cache aliasing code */
+ +++++++ aliasing_icache = 0;
+ +++++++ }
+ +++++++
+ +++++++ return aliasing_icache;
+ +++++++}
+ +++++++
static void __init cacheid_init(void)
{
unsigned int cachetype = read_cpuid_cachetype();
cacheid = CACHEID_VIPT_NONALIASING;
if ((cachetype & (3 << 14)) == 1 << 14)
cacheid |= CACHEID_ASID_TAGGED;
- ------- } else if (cachetype & (1 << 23))
+ +++++++ else if (cpu_has_aliasing_icache(CPU_ARCH_ARMv7))
+ +++++++ cacheid |= CACHEID_VIPT_I_ALIASING;
+ +++++++ } else if (cachetype & (1 << 23)) {
cacheid = CACHEID_VIPT_ALIASING;
- ------- else
+ +++++++ } else {
cacheid = CACHEID_VIPT_NONALIASING;
+ +++++++ if (cpu_has_aliasing_icache(CPU_ARCH_ARMv6))
+ +++++++ cacheid |= CACHEID_VIPT_I_ALIASING;
+ +++++++ }
} else {
cacheid = CACHEID_VIVT;
}
cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown",
cache_is_vivt() ? "VIVT" :
icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" :
- ------- cache_is_vipt_aliasing() ? "VIPT aliasing" :
+ +++++++ icache_is_vipt_aliasing() ? "VIPT aliasing" :
cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown");
}
kernel_code.start = virt_to_phys(_text);
kernel_code.end = virt_to_phys(_etext - 1);
---- ---- kernel_data.start = virt_to_phys(_data);
++++ ++++ kernel_data.start = virt_to_phys(_sdata);
kernel_data.end = virt_to_phys(_end - 1);
for (i = 0; i < mi->nr_banks; i++) {
request_standard_resources(&meminfo, mdesc);
#ifdef CONFIG_SMP
---- ---- smp_init_cpus();
++++ ++++ if (is_smp())
++++ ++++ smp_init_cpus();
#endif
reserve_crashkernel();