Commit c35102c3 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 20107f84 4b46d641
......@@ -414,9 +414,14 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page
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"
:
: "r" (0));
#endif
}
#define ARCH_HAS_FLUSH_ANON_PAGE
......
/*
* 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
* 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_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.
......@@ -48,6 +49,18 @@ const unsigned long sigreturn_codes[7] = {
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.
*/
......@@ -645,32 +658,12 @@ static void do_signal(struct pt_regs *regs, int syscall)
regs->ARM_pc -= 4;
#else
u32 __user *usp;
u32 swival = __NR_restart_syscall;
regs->ARM_sp -= 12;
regs->ARM_sp -= 4;
usp = (u32 __user *)regs->ARM_sp;
/*
* Either we supports 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.
*/
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;
put_user(regs->ARM_pc, usp);
regs->ARM_pc = KERN_RESTART_CODE;
#endif
}
}
......
/*
* 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
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#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 syscall_restart_code[2];
/*
* 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
*
* 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,
sizeof(sigreturn_codes));
memcpy((void *)KERN_RESTART_CODE, syscall_restart_code,
sizeof(syscall_restart_code));
flush_icache_range(vectors, vectors + PAGE_SIZE);
modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
......
......@@ -26,6 +26,15 @@
* 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/init.h>
#include <linux/module.h>
......
......@@ -28,5 +28,6 @@
#define BUS_OFFSET UL(0x80000000)
#define __virt_to_bus(x) ((x) - PAGE_OFFSET + BUS_OFFSET)
#define __bus_to_virt(x) ((x) - BUS_OFFSET + PAGE_OFFSET)
#define __pfn_to_bus(x) (((x) << PAGE_SHIFT) + BUS_OFFSET)
#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_eth_register(const char *name, struct resource *res);
extern int realview_usb_register(struct resource *res);
extern void (*realview_reset)(char);
#endif
......@@ -73,4 +73,9 @@
#define REALVIEW_PB1176_GIC_DIST_BASE 0x10041000 /* GIC distributor, on FPGA */
#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 */
......@@ -81,4 +81,16 @@
#define REALVIEW_TC11MP_GIC_DIST_BASE 0x1F001000 /* Test chip interrupt controller distributor */
#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 */
......@@ -119,19 +119,6 @@
#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)
/*
* 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
* ------------------------------------------------------------------------
......@@ -153,7 +140,7 @@
* SYS_CLD, SYS_BOOTCS
*/
#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
......
......@@ -25,6 +25,8 @@
#include <mach/hardware.h>
#include <mach/platform.h>
void (*realview_reset)(char mode);
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)
{
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_SYS_CTRL_RESET_CONFIGCLR;
__raw_writel(val, hdr_ctrl);
if (realview_reset)
realview_reset(mode);
}
#endif
......@@ -290,6 +290,16 @@ static struct sys_timer realview_pb1176_timer = {
.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)
{
int i;
......@@ -313,6 +323,7 @@ static void __init realview_pb1176_init(void)
#ifdef CONFIG_LEDS
leds_event = realview_leds_event;
#endif
realview_reset = realview_pb1176_reset;
}
MACHINE_START(REALVIEW_PB1176, "ARM-RealView PB1176")
......
......@@ -299,6 +299,21 @@ static struct sys_timer realview_pb11mp_timer = {
.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)
{
int i;
......@@ -324,6 +339,7 @@ static void __init realview_pb11mp_init(void)
#ifdef CONFIG_LEDS
leds_event = realview_leds_event;
#endif
realview_reset = realview_pb11mp_reset;
}
MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore")
......
......@@ -50,10 +50,7 @@ void __new_context(struct mm_struct *mm)
isb();
flush_tlb_all();
if (icache_is_vivt_asid_tagged()) {
asm("mcr p15, 0, %0, c7, c5, 0 @ invalidate I-cache\n"
"mcr p15, 0, %0, c7, c5, 6 @ flush BTAC/BTB\n"
:
: "r" (0));
__flush_icache_all();
dsb();
}
}
......
......@@ -205,7 +205,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
order = get_order(size);
if (mask != 0xffffffff)
if (mask < 0xffffffffULL)
gfp |= GFP_DMA;
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)
goto error;
if (mask != 0xffffffff)
if (mask < 0xffffffffULL)
gfp |= GFP_DMA;
virt = kmalloc(size, gfp);
if (!virt)
......
......@@ -18,10 +18,6 @@
#include "mm.h"
#ifdef CONFIG_ARM_ERRATA_411920
extern void v6_icache_inval_all(void);
#endif
#ifdef CONFIG_CPU_CACHE_VIPT
#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);
asm( "mcrr p15, 0, %1, %0, c14\n"
" mcr p15, 0, %2, c7, c10, 4\n"
#ifndef CONFIG_ARM_ERRATA_411920
" mcr p15, 0, %2, c7, c5, 0\n"
#endif
" mcr p15, 0, %2, c7, c10, 4"
:
: "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES), "r" (zero)
: "cc");
#ifdef CONFIG_ARM_ERRATA_411920
v6_icache_inval_all();
#endif
__flush_icache_all();
}
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()) {
asm( "mcr p15, 0, %0, c7, c14, 0\n"
" mcr p15, 0, %0, c7, c10, 4\n"
#ifndef CONFIG_ARM_ERRATA_411920
" mcr p15, 0, %0, c7, c5, 0\n"
#endif
" mcr p15, 0, %0, c7, c10, 4"
:
: "r" (0)
: "cc");
#ifdef CONFIG_ARM_ERRATA_411920
v6_icache_inval_all();
#endif
__flush_icache_all();
}
}
......@@ -81,16 +67,11 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned
if (cache_is_vipt_aliasing()) {
asm( "mcr p15, 0, %0, c7, c14, 0\n"
" mcr p15, 0, %0, c7, c10, 4\n"
#ifndef CONFIG_ARM_ERRATA_411920
" mcr p15, 0, %0, c7, c5, 0\n"
#endif
" mcr p15, 0, %0, c7, c10, 4"
:
: "r" (0)
: "cc");
#ifdef CONFIG_ARM_ERRATA_411920
v6_icache_inval_all();
#endif
__flush_icache_all();
}
}
......
......@@ -273,7 +273,6 @@ static void __init bootmem_init_node(int node, struct meminfo *mi,
struct membank *bank = &mi->bank[i];
if (!bank->highmem)
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;
}
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
static int __init meminfo_cmp(const void *_a, const void *_b)
......@@ -427,6 +439,12 @@ void __init bootmem_init(void)
*/
if (node == 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))
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) {
printk(KERN_WARNING "Only cachepolicy=writeback supported on ARMv6 and later\n");
cachepolicy = CPOLICY_WRITEBACK;
......
......@@ -32,8 +32,10 @@
#ifndef CONFIG_SMP
#define TTB_FLAGS TTB_RGN_WBWA
#define PMD_FLAGS PMD_SECT_WB
#else
#define TTB_FLAGS TTB_RGN_WBWA|TTB_S
#define PMD_FLAGS PMD_SECT_WBWA|PMD_SECT_S
#endif
ENTRY(cpu_v6_proc_init)
......@@ -222,10 +224,9 @@ __v6_proc_info:
.long 0x0007b000
.long 0x0007f000
.long PMD_TYPE_SECT | \
PMD_SECT_BUFFERABLE | \
PMD_SECT_CACHEABLE | \
PMD_SECT_AP_WRITE | \
PMD_SECT_AP_READ
PMD_SECT_AP_READ | \
PMD_FLAGS
.long PMD_TYPE_SECT | \
PMD_SECT_XN | \
PMD_SECT_AP_WRITE | \
......
......@@ -33,9 +33,11 @@
#ifndef CONFIG_SMP
/* PTWs cacheable, inner WB not shareable, outer WB not shareable */
#define TTB_FLAGS TTB_IRGN_WB|TTB_RGN_OC_WB
#define PMD_FLAGS PMD_SECT_WB
#else
/* PTWs cacheable, inner WBWA shareable, outer WBWA not shareable */
#define TTB_FLAGS TTB_IRGN_WBWA|TTB_S|TTB_NOS|TTB_RGN_OC_WBWA
#define PMD_FLAGS PMD_SECT_WBWA|PMD_SECT_S
#endif
ENTRY(cpu_v7_proc_init)
......@@ -326,10 +328,9 @@ __v7_proc_info:
.long 0x000f0000 @ Required ID value
.long 0x000f0000 @ Mask for ID
.long PMD_TYPE_SECT | \
PMD_SECT_BUFFERABLE | \
PMD_SECT_CACHEABLE | \
PMD_SECT_AP_WRITE | \
PMD_SECT_AP_READ
PMD_SECT_AP_READ | \
PMD_FLAGS
.long PMD_TYPE_SECT | \
PMD_SECT_XN | \
PMD_SECT_AP_WRITE | \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment