Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm: ARM: ensure initial page tables are setup for SMP systems ARM: 5776/1: Check compiler version and EABI support when adding ARM unwind support. ARM: 5774/1: Fix Realview ARM1176PB board reboot ARM: Fix errata 411920 workarounds ARM: Fix sparsemem with SPARSEMEM_EXTREME enabled ARM: Use GFP_DMA only for masks _less_ than 32-bit ARM: integrator: allow Integrator to be built with highmem ARM: Fix signal restart issues with NX and OABI compat
This commit is contained in:
commit
c35102c3e1
20 changed files with 131 additions and 85 deletions
|
@ -414,9 +414,14 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page
|
||||||
|
|
||||||
static inline void __flush_icache_all(void)
|
static inline void __flush_icache_all(void)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_ARM_ERRATA_411920
|
||||||
|
extern void v6_icache_inval_all(void);
|
||||||
|
v6_icache_inval_all();
|
||||||
|
#else
|
||||||
asm("mcr p15, 0, %0, c7, c5, 0 @ invalidate I-cache\n"
|
asm("mcr p15, 0, %0, c7, c5, 0 @ invalidate I-cache\n"
|
||||||
:
|
:
|
||||||
: "r" (0));
|
: "r" (0));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ARCH_HAS_FLUSH_ANON_PAGE
|
#define ARCH_HAS_FLUSH_ANON_PAGE
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* linux/arch/arm/kernel/signal.c
|
* linux/arch/arm/kernel/signal.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 1995-2002 Russell King
|
* Copyright (C) 1995-2009 Russell King
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
@ -29,6 +29,7 @@
|
||||||
*/
|
*/
|
||||||
#define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE))
|
#define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE))
|
||||||
#define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE))
|
#define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE))
|
||||||
|
#define SWI_SYS_RESTART (0xef000000|__NR_restart_syscall|__NR_OABI_SYSCALL_BASE)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* With EABI, the syscall number has to be loaded into r7.
|
* With EABI, the syscall number has to be loaded into r7.
|
||||||
|
@ -48,6 +49,18 @@ const unsigned long sigreturn_codes[7] = {
|
||||||
MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN,
|
MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Either we support OABI only, or we have EABI with the OABI
|
||||||
|
* compat layer enabled. In the later case we don't know if
|
||||||
|
* user space is EABI or not, and if not we must not clobber r7.
|
||||||
|
* Always using the OABI syscall solves that issue and works for
|
||||||
|
* all those cases.
|
||||||
|
*/
|
||||||
|
const unsigned long syscall_restart_code[2] = {
|
||||||
|
SWI_SYS_RESTART, /* swi __NR_restart_syscall */
|
||||||
|
0xe49df004, /* ldr pc, [sp], #4 */
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* atomically swap in the new signal mask, and wait for a signal.
|
* atomically swap in the new signal mask, and wait for a signal.
|
||||||
*/
|
*/
|
||||||
|
@ -645,32 +658,12 @@ static void do_signal(struct pt_regs *regs, int syscall)
|
||||||
regs->ARM_pc -= 4;
|
regs->ARM_pc -= 4;
|
||||||
#else
|
#else
|
||||||
u32 __user *usp;
|
u32 __user *usp;
|
||||||
u32 swival = __NR_restart_syscall;
|
|
||||||
|
|
||||||
regs->ARM_sp -= 12;
|
regs->ARM_sp -= 4;
|
||||||
usp = (u32 __user *)regs->ARM_sp;
|
usp = (u32 __user *)regs->ARM_sp;
|
||||||
|
|
||||||
/*
|
put_user(regs->ARM_pc, usp);
|
||||||
* Either we supports OABI only, or we have
|
regs->ARM_pc = KERN_RESTART_CODE;
|
||||||
* EABI with the OABI compat layer enabled.
|
|
||||||
* In the later case we don't know if user
|
|
||||||
* space is EABI or not, and if not we must
|
|
||||||
* not clobber r7. Always using the OABI
|
|
||||||
* syscall solves that issue and works for
|
|
||||||
* all those cases.
|
|
||||||
*/
|
|
||||||
swival = swival - __NR_SYSCALL_BASE + __NR_OABI_SYSCALL_BASE;
|
|
||||||
|
|
||||||
put_user(regs->ARM_pc, &usp[0]);
|
|
||||||
/* swi __NR_restart_syscall */
|
|
||||||
put_user(0xef000000 | swival, &usp[1]);
|
|
||||||
/* ldr pc, [sp], #12 */
|
|
||||||
put_user(0xe49df00c, &usp[2]);
|
|
||||||
|
|
||||||
flush_icache_range((unsigned long)usp,
|
|
||||||
(unsigned long)(usp + 3));
|
|
||||||
|
|
||||||
regs->ARM_pc = regs->ARM_sp + 4;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
/*
|
/*
|
||||||
* linux/arch/arm/kernel/signal.h
|
* linux/arch/arm/kernel/signal.h
|
||||||
*
|
*
|
||||||
* Copyright (C) 2005 Russell King.
|
* Copyright (C) 2005-2009 Russell King.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation.
|
||||||
*/
|
*/
|
||||||
#define KERN_SIGRETURN_CODE (CONFIG_VECTORS_BASE + 0x00000500)
|
#define KERN_SIGRETURN_CODE (CONFIG_VECTORS_BASE + 0x00000500)
|
||||||
|
#define KERN_RESTART_CODE (KERN_SIGRETURN_CODE + sizeof(sigreturn_codes))
|
||||||
|
|
||||||
extern const unsigned long sigreturn_codes[7];
|
extern const unsigned long sigreturn_codes[7];
|
||||||
|
extern const unsigned long syscall_restart_code[2];
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* linux/arch/arm/kernel/traps.c
|
* linux/arch/arm/kernel/traps.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 1995-2002 Russell King
|
* Copyright (C) 1995-2009 Russell King
|
||||||
* Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds
|
* Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -751,6 +751,8 @@ void __init early_trap_init(void)
|
||||||
*/
|
*/
|
||||||
memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes,
|
memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes,
|
||||||
sizeof(sigreturn_codes));
|
sizeof(sigreturn_codes));
|
||||||
|
memcpy((void *)KERN_RESTART_CODE, syscall_restart_code,
|
||||||
|
sizeof(syscall_restart_code));
|
||||||
|
|
||||||
flush_icache_range(vectors, vectors + PAGE_SIZE);
|
flush_icache_range(vectors, vectors + PAGE_SIZE);
|
||||||
modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
|
modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
|
||||||
|
|
|
@ -26,6 +26,15 @@
|
||||||
* http://infocenter.arm.com/help/topic/com.arm.doc.subset.swdev.abi/index.html
|
* http://infocenter.arm.com/help/topic/com.arm.doc.subset.swdev.abi/index.html
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if !defined (__ARM_EABI__)
|
||||||
|
#warning Your compiler does not have EABI support.
|
||||||
|
#warning ARM unwind is known to compile only with EABI compilers.
|
||||||
|
#warning Change compiler or disable ARM_UNWIND option.
|
||||||
|
#elif (__GNUC__ == 4 && __GNUC_MINOR__ <= 2)
|
||||||
|
#warning Your compiler is too buggy; it is known to not compile ARM unwind support.
|
||||||
|
#warning Change compiler or disable ARM_UNWIND option.
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
|
|
@ -28,5 +28,6 @@
|
||||||
#define BUS_OFFSET UL(0x80000000)
|
#define BUS_OFFSET UL(0x80000000)
|
||||||
#define __virt_to_bus(x) ((x) - PAGE_OFFSET + BUS_OFFSET)
|
#define __virt_to_bus(x) ((x) - PAGE_OFFSET + BUS_OFFSET)
|
||||||
#define __bus_to_virt(x) ((x) - BUS_OFFSET + PAGE_OFFSET)
|
#define __bus_to_virt(x) ((x) - BUS_OFFSET + PAGE_OFFSET)
|
||||||
|
#define __pfn_to_bus(x) (((x) << PAGE_SHIFT) + BUS_OFFSET)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -61,5 +61,5 @@ extern void realview_timer_init(unsigned int timer_irq);
|
||||||
extern int realview_flash_register(struct resource *res, u32 num);
|
extern int realview_flash_register(struct resource *res, u32 num);
|
||||||
extern int realview_eth_register(const char *name, struct resource *res);
|
extern int realview_eth_register(const char *name, struct resource *res);
|
||||||
extern int realview_usb_register(struct resource *res);
|
extern int realview_usb_register(struct resource *res);
|
||||||
|
extern void (*realview_reset)(char);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -73,4 +73,9 @@
|
||||||
#define REALVIEW_PB1176_GIC_DIST_BASE 0x10041000 /* GIC distributor, on FPGA */
|
#define REALVIEW_PB1176_GIC_DIST_BASE 0x10041000 /* GIC distributor, on FPGA */
|
||||||
#define REALVIEW_PB1176_L220_BASE 0x10110000 /* L220 registers */
|
#define REALVIEW_PB1176_L220_BASE 0x10110000 /* L220 registers */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Control register SYS_RESETCTL is set to 1 to force a soft reset
|
||||||
|
*/
|
||||||
|
#define REALVIEW_PB1176_SYS_LOCKVAL_RSTCTL 0x0100
|
||||||
|
|
||||||
#endif /* __ASM_ARCH_BOARD_PB1176_H */
|
#endif /* __ASM_ARCH_BOARD_PB1176_H */
|
||||||
|
|
|
@ -81,4 +81,16 @@
|
||||||
#define REALVIEW_TC11MP_GIC_DIST_BASE 0x1F001000 /* Test chip interrupt controller distributor */
|
#define REALVIEW_TC11MP_GIC_DIST_BASE 0x1F001000 /* Test chip interrupt controller distributor */
|
||||||
#define REALVIEW_TC11MP_L220_BASE 0x1F002000 /* L220 registers */
|
#define REALVIEW_TC11MP_L220_BASE 0x1F002000 /* L220 registers */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Values for REALVIEW_SYS_RESET_CTRL
|
||||||
|
*/
|
||||||
|
#define REALVIEW_PB11MP_SYS_CTRL_RESET_CONFIGCLR 0x01
|
||||||
|
#define REALVIEW_PB11MP_SYS_CTRL_RESET_CONFIGINIT 0x02
|
||||||
|
#define REALVIEW_PB11MP_SYS_CTRL_RESET_DLLRESET 0x03
|
||||||
|
#define REALVIEW_PB11MP_SYS_CTRL_RESET_PLLRESET 0x04
|
||||||
|
#define REALVIEW_PB11MP_SYS_CTRL_RESET_POR 0x05
|
||||||
|
#define REALVIEW_PB11MP_SYS_CTRL_RESET_DoC 0x06
|
||||||
|
|
||||||
|
#define REALVIEW_PB11MP_SYS_CTRL_LED (1 << 0)
|
||||||
|
|
||||||
#endif /* __ASM_ARCH_BOARD_PB11MP_H */
|
#endif /* __ASM_ARCH_BOARD_PB11MP_H */
|
||||||
|
|
|
@ -119,19 +119,6 @@
|
||||||
#define REALVIEW_SYS_TEST_OSC3 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC3_OFFSET)
|
#define REALVIEW_SYS_TEST_OSC3 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC3_OFFSET)
|
||||||
#define REALVIEW_SYS_TEST_OSC4 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC4_OFFSET)
|
#define REALVIEW_SYS_TEST_OSC4 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC4_OFFSET)
|
||||||
|
|
||||||
/*
|
|
||||||
* Values for REALVIEW_SYS_RESET_CTRL
|
|
||||||
*/
|
|
||||||
#define REALVIEW_SYS_CTRL_RESET_CONFIGCLR 0x01
|
|
||||||
#define REALVIEW_SYS_CTRL_RESET_CONFIGINIT 0x02
|
|
||||||
#define REALVIEW_SYS_CTRL_RESET_DLLRESET 0x03
|
|
||||||
#define REALVIEW_SYS_CTRL_RESET_PLLRESET 0x04
|
|
||||||
#define REALVIEW_SYS_CTRL_RESET_POR 0x05
|
|
||||||
#define REALVIEW_SYS_CTRL_RESET_DoC 0x06
|
|
||||||
|
|
||||||
#define REALVIEW_SYS_CTRL_LED (1 << 0)
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------
|
||||||
* RealView control registers
|
* RealView control registers
|
||||||
* ------------------------------------------------------------------------
|
* ------------------------------------------------------------------------
|
||||||
|
@ -153,7 +140,7 @@
|
||||||
* SYS_CLD, SYS_BOOTCS
|
* SYS_CLD, SYS_BOOTCS
|
||||||
*/
|
*/
|
||||||
#define REALVIEW_SYS_LOCK_LOCKED (1 << 16)
|
#define REALVIEW_SYS_LOCK_LOCKED (1 << 16)
|
||||||
#define REALVIEW_SYS_LOCKVAL_MASK 0xFFFF /* write 0xA05F to enable write access */
|
#define REALVIEW_SYS_LOCKVAL_MASK 0xA05F /* Enable write access */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* REALVIEW_SYS_FLASH
|
* REALVIEW_SYS_FLASH
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#include <mach/hardware.h>
|
#include <mach/hardware.h>
|
||||||
#include <mach/platform.h>
|
#include <mach/platform.h>
|
||||||
|
|
||||||
|
void (*realview_reset)(char mode);
|
||||||
|
|
||||||
static inline void arch_idle(void)
|
static inline void arch_idle(void)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -36,16 +38,12 @@ static inline void arch_idle(void)
|
||||||
|
|
||||||
static inline void arch_reset(char mode, const char *cmd)
|
static inline void arch_reset(char mode, const char *cmd)
|
||||||
{
|
{
|
||||||
void __iomem *hdr_ctrl = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_RESETCTL_OFFSET;
|
|
||||||
unsigned int val;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* To reset, we hit the on-board reset register
|
* To reset, we hit the on-board reset register
|
||||||
* in the system FPGA
|
* in the system FPGA
|
||||||
*/
|
*/
|
||||||
val = __raw_readl(hdr_ctrl);
|
if (realview_reset)
|
||||||
val |= REALVIEW_SYS_CTRL_RESET_CONFIGCLR;
|
realview_reset(mode);
|
||||||
__raw_writel(val, hdr_ctrl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -290,6 +290,16 @@ static struct sys_timer realview_pb1176_timer = {
|
||||||
.init = realview_pb1176_timer_init,
|
.init = realview_pb1176_timer_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void realview_pb1176_reset(char mode)
|
||||||
|
{
|
||||||
|
void __iomem *hdr_ctrl = __io_address(REALVIEW_SYS_BASE) +
|
||||||
|
REALVIEW_SYS_RESETCTL_OFFSET;
|
||||||
|
void __iomem *rst_hdr_ctrl = __io_address(REALVIEW_SYS_BASE) +
|
||||||
|
REALVIEW_SYS_LOCK_OFFSET;
|
||||||
|
__raw_writel(REALVIEW_SYS_LOCKVAL_MASK, rst_hdr_ctrl);
|
||||||
|
__raw_writel(REALVIEW_PB1176_SYS_LOCKVAL_RSTCTL, hdr_ctrl);
|
||||||
|
}
|
||||||
|
|
||||||
static void __init realview_pb1176_init(void)
|
static void __init realview_pb1176_init(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -313,6 +323,7 @@ static void __init realview_pb1176_init(void)
|
||||||
#ifdef CONFIG_LEDS
|
#ifdef CONFIG_LEDS
|
||||||
leds_event = realview_leds_event;
|
leds_event = realview_leds_event;
|
||||||
#endif
|
#endif
|
||||||
|
realview_reset = realview_pb1176_reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
MACHINE_START(REALVIEW_PB1176, "ARM-RealView PB1176")
|
MACHINE_START(REALVIEW_PB1176, "ARM-RealView PB1176")
|
||||||
|
|
|
@ -299,6 +299,21 @@ static struct sys_timer realview_pb11mp_timer = {
|
||||||
.init = realview_pb11mp_timer_init,
|
.init = realview_pb11mp_timer_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void realview_pb11mp_reset(char mode)
|
||||||
|
{
|
||||||
|
void __iomem *hdr_ctrl = __io_address(REALVIEW_SYS_BASE) +
|
||||||
|
REALVIEW_SYS_RESETCTL_OFFSET;
|
||||||
|
unsigned int val;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To reset, we hit the on-board reset register
|
||||||
|
* in the system FPGA
|
||||||
|
*/
|
||||||
|
val = __raw_readl(hdr_ctrl);
|
||||||
|
val |= REALVIEW_PB11MP_SYS_CTRL_RESET_CONFIGCLR;
|
||||||
|
__raw_writel(val, hdr_ctrl);
|
||||||
|
}
|
||||||
|
|
||||||
static void __init realview_pb11mp_init(void)
|
static void __init realview_pb11mp_init(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -324,6 +339,7 @@ static void __init realview_pb11mp_init(void)
|
||||||
#ifdef CONFIG_LEDS
|
#ifdef CONFIG_LEDS
|
||||||
leds_event = realview_leds_event;
|
leds_event = realview_leds_event;
|
||||||
#endif
|
#endif
|
||||||
|
realview_reset = realview_pb11mp_reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore")
|
MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore")
|
||||||
|
|
|
@ -50,10 +50,7 @@ void __new_context(struct mm_struct *mm)
|
||||||
isb();
|
isb();
|
||||||
flush_tlb_all();
|
flush_tlb_all();
|
||||||
if (icache_is_vivt_asid_tagged()) {
|
if (icache_is_vivt_asid_tagged()) {
|
||||||
asm("mcr p15, 0, %0, c7, c5, 0 @ invalidate I-cache\n"
|
__flush_icache_all();
|
||||||
"mcr p15, 0, %0, c7, c5, 6 @ flush BTAC/BTB\n"
|
|
||||||
:
|
|
||||||
: "r" (0));
|
|
||||||
dsb();
|
dsb();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -205,7 +205,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
|
||||||
|
|
||||||
order = get_order(size);
|
order = get_order(size);
|
||||||
|
|
||||||
if (mask != 0xffffffff)
|
if (mask < 0xffffffffULL)
|
||||||
gfp |= GFP_DMA;
|
gfp |= GFP_DMA;
|
||||||
|
|
||||||
page = alloc_pages(gfp, order);
|
page = alloc_pages(gfp, order);
|
||||||
|
@ -289,7 +289,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
|
||||||
if (!mask)
|
if (!mask)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (mask != 0xffffffff)
|
if (mask < 0xffffffffULL)
|
||||||
gfp |= GFP_DMA;
|
gfp |= GFP_DMA;
|
||||||
virt = kmalloc(size, gfp);
|
virt = kmalloc(size, gfp);
|
||||||
if (!virt)
|
if (!virt)
|
||||||
|
|
|
@ -18,10 +18,6 @@
|
||||||
|
|
||||||
#include "mm.h"
|
#include "mm.h"
|
||||||
|
|
||||||
#ifdef CONFIG_ARM_ERRATA_411920
|
|
||||||
extern void v6_icache_inval_all(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_CPU_CACHE_VIPT
|
#ifdef CONFIG_CPU_CACHE_VIPT
|
||||||
|
|
||||||
#define ALIAS_FLUSH_START 0xffff4000
|
#define ALIAS_FLUSH_START 0xffff4000
|
||||||
|
@ -35,16 +31,11 @@ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
|
||||||
flush_tlb_kernel_page(to);
|
flush_tlb_kernel_page(to);
|
||||||
|
|
||||||
asm( "mcrr p15, 0, %1, %0, c14\n"
|
asm( "mcrr p15, 0, %1, %0, c14\n"
|
||||||
" mcr p15, 0, %2, c7, c10, 4\n"
|
" mcr p15, 0, %2, c7, c10, 4"
|
||||||
#ifndef CONFIG_ARM_ERRATA_411920
|
|
||||||
" mcr p15, 0, %2, c7, c5, 0\n"
|
|
||||||
#endif
|
|
||||||
:
|
:
|
||||||
: "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES), "r" (zero)
|
: "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES), "r" (zero)
|
||||||
: "cc");
|
: "cc");
|
||||||
#ifdef CONFIG_ARM_ERRATA_411920
|
__flush_icache_all();
|
||||||
v6_icache_inval_all();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void flush_cache_mm(struct mm_struct *mm)
|
void flush_cache_mm(struct mm_struct *mm)
|
||||||
|
@ -57,16 +48,11 @@ void flush_cache_mm(struct mm_struct *mm)
|
||||||
|
|
||||||
if (cache_is_vipt_aliasing()) {
|
if (cache_is_vipt_aliasing()) {
|
||||||
asm( "mcr p15, 0, %0, c7, c14, 0\n"
|
asm( "mcr p15, 0, %0, c7, c14, 0\n"
|
||||||
" mcr p15, 0, %0, c7, c10, 4\n"
|
" mcr p15, 0, %0, c7, c10, 4"
|
||||||
#ifndef CONFIG_ARM_ERRATA_411920
|
|
||||||
" mcr p15, 0, %0, c7, c5, 0\n"
|
|
||||||
#endif
|
|
||||||
:
|
:
|
||||||
: "r" (0)
|
: "r" (0)
|
||||||
: "cc");
|
: "cc");
|
||||||
#ifdef CONFIG_ARM_ERRATA_411920
|
__flush_icache_all();
|
||||||
v6_icache_inval_all();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,16 +67,11 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned
|
||||||
|
|
||||||
if (cache_is_vipt_aliasing()) {
|
if (cache_is_vipt_aliasing()) {
|
||||||
asm( "mcr p15, 0, %0, c7, c14, 0\n"
|
asm( "mcr p15, 0, %0, c7, c14, 0\n"
|
||||||
" mcr p15, 0, %0, c7, c10, 4\n"
|
" mcr p15, 0, %0, c7, c10, 4"
|
||||||
#ifndef CONFIG_ARM_ERRATA_411920
|
|
||||||
" mcr p15, 0, %0, c7, c5, 0\n"
|
|
||||||
#endif
|
|
||||||
:
|
:
|
||||||
: "r" (0)
|
: "r" (0)
|
||||||
: "cc");
|
: "cc");
|
||||||
#ifdef CONFIG_ARM_ERRATA_411920
|
__flush_icache_all();
|
||||||
v6_icache_inval_all();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -273,7 +273,6 @@ static void __init bootmem_init_node(int node, struct meminfo *mi,
|
||||||
struct membank *bank = &mi->bank[i];
|
struct membank *bank = &mi->bank[i];
|
||||||
if (!bank->highmem)
|
if (!bank->highmem)
|
||||||
free_bootmem_node(pgdat, bank_phys_start(bank), bank_phys_size(bank));
|
free_bootmem_node(pgdat, bank_phys_start(bank), bank_phys_size(bank));
|
||||||
memory_present(node, bank_pfn_start(bank), bank_pfn_end(bank));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -370,6 +369,19 @@ int pfn_valid(unsigned long pfn)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(pfn_valid);
|
EXPORT_SYMBOL(pfn_valid);
|
||||||
|
|
||||||
|
static void arm_memory_present(struct meminfo *mi, int node)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static void arm_memory_present(struct meminfo *mi, int node)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for_each_nodebank(i, mi, node) {
|
||||||
|
struct membank *bank = &mi->bank[i];
|
||||||
|
memory_present(node, bank_pfn_start(bank), bank_pfn_end(bank));
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int __init meminfo_cmp(const void *_a, const void *_b)
|
static int __init meminfo_cmp(const void *_a, const void *_b)
|
||||||
|
@ -427,6 +439,12 @@ void __init bootmem_init(void)
|
||||||
*/
|
*/
|
||||||
if (node == initrd_node)
|
if (node == initrd_node)
|
||||||
bootmem_reserve_initrd(node);
|
bootmem_reserve_initrd(node);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sparsemem tries to allocate bootmem in memory_present(),
|
||||||
|
* so must be done after the fixed reservations
|
||||||
|
*/
|
||||||
|
arm_memory_present(mi, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -117,6 +117,13 @@ static void __init early_cachepolicy(char **p)
|
||||||
}
|
}
|
||||||
if (i == ARRAY_SIZE(cache_policies))
|
if (i == ARRAY_SIZE(cache_policies))
|
||||||
printk(KERN_ERR "ERROR: unknown or unsupported cache policy\n");
|
printk(KERN_ERR "ERROR: unknown or unsupported cache policy\n");
|
||||||
|
/*
|
||||||
|
* This restriction is partly to do with the way we boot; it is
|
||||||
|
* unpredictable to have memory mapped using two different sets of
|
||||||
|
* memory attributes (shared, type, and cache attribs). We can not
|
||||||
|
* change these attributes once the initial assembly has setup the
|
||||||
|
* page tables.
|
||||||
|
*/
|
||||||
if (cpu_architecture() >= CPU_ARCH_ARMv6) {
|
if (cpu_architecture() >= CPU_ARCH_ARMv6) {
|
||||||
printk(KERN_WARNING "Only cachepolicy=writeback supported on ARMv6 and later\n");
|
printk(KERN_WARNING "Only cachepolicy=writeback supported on ARMv6 and later\n");
|
||||||
cachepolicy = CPOLICY_WRITEBACK;
|
cachepolicy = CPOLICY_WRITEBACK;
|
||||||
|
|
|
@ -32,8 +32,10 @@
|
||||||
|
|
||||||
#ifndef CONFIG_SMP
|
#ifndef CONFIG_SMP
|
||||||
#define TTB_FLAGS TTB_RGN_WBWA
|
#define TTB_FLAGS TTB_RGN_WBWA
|
||||||
|
#define PMD_FLAGS PMD_SECT_WB
|
||||||
#else
|
#else
|
||||||
#define TTB_FLAGS TTB_RGN_WBWA|TTB_S
|
#define TTB_FLAGS TTB_RGN_WBWA|TTB_S
|
||||||
|
#define PMD_FLAGS PMD_SECT_WBWA|PMD_SECT_S
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ENTRY(cpu_v6_proc_init)
|
ENTRY(cpu_v6_proc_init)
|
||||||
|
@ -222,10 +224,9 @@ __v6_proc_info:
|
||||||
.long 0x0007b000
|
.long 0x0007b000
|
||||||
.long 0x0007f000
|
.long 0x0007f000
|
||||||
.long PMD_TYPE_SECT | \
|
.long PMD_TYPE_SECT | \
|
||||||
PMD_SECT_BUFFERABLE | \
|
|
||||||
PMD_SECT_CACHEABLE | \
|
|
||||||
PMD_SECT_AP_WRITE | \
|
PMD_SECT_AP_WRITE | \
|
||||||
PMD_SECT_AP_READ
|
PMD_SECT_AP_READ | \
|
||||||
|
PMD_FLAGS
|
||||||
.long PMD_TYPE_SECT | \
|
.long PMD_TYPE_SECT | \
|
||||||
PMD_SECT_XN | \
|
PMD_SECT_XN | \
|
||||||
PMD_SECT_AP_WRITE | \
|
PMD_SECT_AP_WRITE | \
|
||||||
|
|
|
@ -33,9 +33,11 @@
|
||||||
#ifndef CONFIG_SMP
|
#ifndef CONFIG_SMP
|
||||||
/* PTWs cacheable, inner WB not shareable, outer WB not shareable */
|
/* PTWs cacheable, inner WB not shareable, outer WB not shareable */
|
||||||
#define TTB_FLAGS TTB_IRGN_WB|TTB_RGN_OC_WB
|
#define TTB_FLAGS TTB_IRGN_WB|TTB_RGN_OC_WB
|
||||||
|
#define PMD_FLAGS PMD_SECT_WB
|
||||||
#else
|
#else
|
||||||
/* PTWs cacheable, inner WBWA shareable, outer WBWA not shareable */
|
/* PTWs cacheable, inner WBWA shareable, outer WBWA not shareable */
|
||||||
#define TTB_FLAGS TTB_IRGN_WBWA|TTB_S|TTB_NOS|TTB_RGN_OC_WBWA
|
#define TTB_FLAGS TTB_IRGN_WBWA|TTB_S|TTB_NOS|TTB_RGN_OC_WBWA
|
||||||
|
#define PMD_FLAGS PMD_SECT_WBWA|PMD_SECT_S
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ENTRY(cpu_v7_proc_init)
|
ENTRY(cpu_v7_proc_init)
|
||||||
|
@ -326,10 +328,9 @@ __v7_proc_info:
|
||||||
.long 0x000f0000 @ Required ID value
|
.long 0x000f0000 @ Required ID value
|
||||||
.long 0x000f0000 @ Mask for ID
|
.long 0x000f0000 @ Mask for ID
|
||||||
.long PMD_TYPE_SECT | \
|
.long PMD_TYPE_SECT | \
|
||||||
PMD_SECT_BUFFERABLE | \
|
|
||||||
PMD_SECT_CACHEABLE | \
|
|
||||||
PMD_SECT_AP_WRITE | \
|
PMD_SECT_AP_WRITE | \
|
||||||
PMD_SECT_AP_READ
|
PMD_SECT_AP_READ | \
|
||||||
|
PMD_FLAGS
|
||||||
.long PMD_TYPE_SECT | \
|
.long PMD_TYPE_SECT | \
|
||||||
PMD_SECT_XN | \
|
PMD_SECT_XN | \
|
||||||
PMD_SECT_AP_WRITE | \
|
PMD_SECT_AP_WRITE | \
|
||||||
|
|
Loading…
Reference in a new issue