Commit 2954a9c4 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://bk.arm.linux.org.uk/linux-2.6-rmk

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents 7b705459 a25b8487
This diff is collapsed.
...@@ -1657,6 +1657,8 @@ __stubs_end: ...@@ -1657,6 +1657,8 @@ __stubs_end:
ENTRY(__trap_init) ENTRY(__trap_init)
stmfd sp!, {r4 - r6, lr} stmfd sp!, {r4 - r6, lr}
mov r0, #0xff000000
orr r0, r0, #0x00ff0000 @ high vectors position
adr r1, .LCvectors @ set up the vectors adr r1, .LCvectors @ set up the vectors
ldmia r1, {r1, r2, r3, r4, r5, r6, ip, lr} ldmia r1, {r1, r2, r3, r4, r5, r6, ip, lr}
stmia r0, {r1, r2, r3, r4, r5, r6, ip, lr} stmia r0, {r1, r2, r3, r4, r5, r6, ip, lr}
......
...@@ -46,32 +46,16 @@ ...@@ -46,32 +46,16 @@
#include <asm/system.h> #include <asm/system.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#define FIQ_VECTOR (vectors_base() + 0x1c)
static unsigned long no_fiq_insn; static unsigned long no_fiq_insn;
static inline void unprotect_page_0(void)
{
modify_domain(DOMAIN_USER, DOMAIN_MANAGER);
}
static inline void protect_page_0(void)
{
modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
}
/* Default reacquire function /* Default reacquire function
* - we always relinquish FIQ control * - we always relinquish FIQ control
* - we always reacquire FIQ control * - we always reacquire FIQ control
*/ */
static int fiq_def_op(void *ref, int relinquish) static int fiq_def_op(void *ref, int relinquish)
{ {
if (!relinquish) { if (!relinquish)
unprotect_page_0(); set_fiq_handler(&no_fiq_insn, sizeof(no_fiq_insn));
*(unsigned long *)FIQ_VECTOR = no_fiq_insn;
protect_page_0();
flush_icache_range(FIQ_VECTOR, FIQ_VECTOR + 4);
}
return 0; return 0;
} }
...@@ -93,12 +77,10 @@ int show_fiq_list(struct seq_file *p, void *v) ...@@ -93,12 +77,10 @@ int show_fiq_list(struct seq_file *p, void *v)
void set_fiq_handler(void *start, unsigned int length) void set_fiq_handler(void *start, unsigned int length)
{ {
unprotect_page_0(); memcpy((void *)0xffff001c, start, length);
flush_icache_range(0xffff001c, 0xffff001c + length);
memcpy((void *)FIQ_VECTOR, start, length); if (!vectors_high())
flush_icache_range(0x1c, 0x1c + length);
protect_page_0();
flush_icache_range(FIQ_VECTOR, FIQ_VECTOR + length);
} }
/* /*
...@@ -198,6 +180,5 @@ EXPORT_SYMBOL(disable_fiq); ...@@ -198,6 +180,5 @@ EXPORT_SYMBOL(disable_fiq);
void __init init_FIQ(void) void __init init_FIQ(void)
{ {
no_fiq_insn = *(unsigned long *)FIQ_VECTOR; no_fiq_insn = *(unsigned long *)0xffff001c;
set_fs(get_fs());
} }
...@@ -51,6 +51,13 @@ asmlinkage int sys_pipe(unsigned long __user *fildes) ...@@ -51,6 +51,13 @@ asmlinkage int sys_pipe(unsigned long __user *fildes)
return error; return error;
} }
/*
* This is the lowest virtual address we can permit any user space
* mapping to be mapped at. This is particularly important for
* non-high vector CPUs.
*/
#define MIN_MAP_ADDR (PAGE_SIZE)
/* common code for old and new mmaps */ /* common code for old and new mmaps */
inline long do_mmap2( inline long do_mmap2(
unsigned long addr, unsigned long len, unsigned long addr, unsigned long len,
...@@ -62,11 +69,7 @@ inline long do_mmap2( ...@@ -62,11 +69,7 @@ inline long do_mmap2(
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
/* if (flags & MAP_FIXED && addr < MIN_MAP_ADDR)
* If we are doing a fixed mapping, and address < PAGE_SIZE,
* then deny it.
*/
if (flags & MAP_FIXED && addr < PAGE_SIZE && vectors_base() == 0)
goto out; goto out;
error = -EBADF; error = -EBADF;
...@@ -119,12 +122,7 @@ sys_arm_mremap(unsigned long addr, unsigned long old_len, ...@@ -119,12 +122,7 @@ sys_arm_mremap(unsigned long addr, unsigned long old_len,
{ {
unsigned long ret = -EINVAL; unsigned long ret = -EINVAL;
/* if (flags & MREMAP_FIXED && new_addr < MIN_MAP_ADDR)
* If we are doing a fixed mapping, and address < PAGE_SIZE,
* then deny it.
*/
if (flags & MREMAP_FIXED && new_addr < PAGE_SIZE &&
vectors_base() == 0)
goto out; goto out;
down_write(&current->mm->mmap_sem); down_write(&current->mm->mmap_sem);
......
...@@ -328,20 +328,11 @@ asmlinkage void do_unexp_fiq (struct pt_regs *regs) ...@@ -328,20 +328,11 @@ asmlinkage void do_unexp_fiq (struct pt_regs *regs)
*/ */
asmlinkage void bad_mode(struct pt_regs *regs, int reason, int proc_mode) asmlinkage void bad_mode(struct pt_regs *regs, int reason, int proc_mode)
{ {
unsigned int vectors = vectors_base();
console_verbose(); console_verbose();
printk(KERN_CRIT "Bad mode in %s handler detected: mode %s\n", printk(KERN_CRIT "Bad mode in %s handler detected: mode %s\n",
handler[reason], processor_modes[proc_mode]); handler[reason], processor_modes[proc_mode]);
/*
* Dump out the vectors and stub routines. Maybe a better solution
* would be to dump them out only if we detect that they are corrupted.
*/
dump_mem(KERN_CRIT "Vectors: ", vectors, vectors + 0x40);
dump_mem(KERN_CRIT "Stubs: ", vectors + 0x200, vectors + 0x4b8);
die("Oops - bad mode", regs, 0); die("Oops - bad mode", regs, 0);
local_irq_disable(); local_irq_disable();
panic("bad mode"); panic("bad mode");
...@@ -537,7 +528,7 @@ EXPORT_SYMBOL(__bug); ...@@ -537,7 +528,7 @@ EXPORT_SYMBOL(__bug);
void __readwrite_bug(const char *fn) void __readwrite_bug(const char *fn)
{ {
printk("%s called, but not implemented", fn); printk("%s called, but not implemented\n", fn);
BUG(); BUG();
} }
EXPORT_SYMBOL(__readwrite_bug); EXPORT_SYMBOL(__readwrite_bug);
...@@ -575,13 +566,9 @@ EXPORT_SYMBOL(abort); ...@@ -575,13 +566,9 @@ EXPORT_SYMBOL(abort);
void __init trap_init(void) void __init trap_init(void)
{ {
extern void __trap_init(unsigned long); extern void __trap_init(void);
unsigned long base = vectors_base();
__trap_init();
__trap_init(base); flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE);
flush_icache_range(base, base + PAGE_SIZE);
if (base != 0)
printk(KERN_DEBUG "Relocating machine vectors to 0x%08lx\n",
base);
modify_domain(DOMAIN_USER, DOMAIN_CLIENT); modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
} }
...@@ -243,7 +243,7 @@ struct clk s3c24xx_dclk1 = { ...@@ -243,7 +243,7 @@ struct clk s3c24xx_dclk1 = {
}; };
struct clk s3c24xx_clkout0 = { struct clk s3c24xx_clkout0 = {
.name = "clkout1", .name = "clkout0",
.id = -1, .id = -1,
}; };
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/hardware.h> #include <asm/hardware.h>
...@@ -18,6 +20,7 @@ ...@@ -18,6 +20,7 @@
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <asm/mach/serial_sa1100.h> #include <asm/mach/serial_sa1100.h>
#include <asm/arch/simpad.h> #include <asm/arch/simpad.h>
...@@ -83,6 +86,45 @@ static struct sa1100_port_fns simpad_port_fns __initdata = { ...@@ -83,6 +86,45 @@ static struct sa1100_port_fns simpad_port_fns __initdata = {
.pm = simpad_uart_pm, .pm = simpad_uart_pm,
}; };
static struct mtd_partition simpad_partitions[] = {
{
.name = "SIMpad boot firmware",
.size = 0x00080000,
.offset = 0,
.mask_flags = MTD_WRITEABLE,
}, {
.name = "SIMpad kernel",
.size = 0x0010000,
.offset = MTDPART_OFS_APPEND,
}, {
.name = "SIMpad root jffs2",
.size = MTDPART_SIZ_FULL,
.offset = MTDPART_OFS_APPEND,
}
};
static struct flash_platform_data simpad_flash_data = {
.map_name = "cfi_probe",
.parts = simpad_partitions,
.nr_parts = ARRAY_SIZE(simpad_partitions),
};
static struct resource simpad_flash_resources [] = {
{
.start = SA1100_CS0_PHYS,
.end = SA1100_CS0_PHYS + SZ_16M -1,
.flags = IORESOURCE_MEM,
}, {
.start = SA1100_CS1_PHYS,
.end = SA1100_CS1_PHYS + SZ_16M -1,
.flags = IORESOURCE_MEM,
}
};
static void __init simpad_map_io(void) static void __init simpad_map_io(void)
{ {
sa1100_map_io(); sa1100_map_io();
...@@ -113,84 +155,9 @@ static void __init simpad_map_io(void) ...@@ -113,84 +155,9 @@ static void __init simpad_map_io(void)
PCFR = 0; PCFR = 0;
PSDR = 0; PSDR = 0;
sa11x0_set_flash_data(&simpad_flash_data, simpad_flash_resources,
} ARRAY_SIZE(simpad_flash_resources));
#ifdef CONFIG_PROC_FS
static char* name[]={
"VCC_5V_EN",
"VCC_3V_EN",
"EN1",
"EN0",
"DISPLAY_ON",
"PCMCIA_BUFF_DIS",
"MQ_RESET",
"PCMCIA_RESET",
"DECT_POWER_ON",
"IRDA_SD",
"RS232_ON",
"SD_MEDIAQ",
"LED2_ON",
"IRDA_MODE",
"ENABLE_5V",
"RESET_SIMCARD"
};
static int proc_cs3_read(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
char *p = page;
int len, i;
p += sprintf(p, "Chipselect3 : %x\n", (uint)cs3_shadow);
for (i = 0; i <= 15; i++) {
if(cs3_shadow & (1<<i)) {
p += sprintf(p, "%s\t: TRUE \n",name[i]);
} else
p += sprintf(p, "%s\t: FALSE \n",name[i]);
}
len = (p - page) - off;
if (len < 0)
len = 0;
*eof = (len <= count) ? 1 : 0;
*start = page + off;
return len;
}
static int proc_cs3_write(struct file * file, const char * buffer,
size_t count, loff_t *ppos)
{
unsigned long newRegValue;
char *endp;
newRegValue = simple_strtoul(buffer,&endp,0);
set_cs3( newRegValue );
return (count+endp-buffer);
}
#endif
static int __init cs3_init(void)
{
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc_cs3 = create_proc_entry("CS3", 0, 0);
if (proc_cs3)
{
proc_cs3->read_proc = proc_cs3_read;
proc_cs3->write_proc = (void*)proc_cs3_write;
}
#endif
return 0;
} }
arch_initcall(cs3_init);
static void simpad_power_off(void) static void simpad_power_off(void)
{ {
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/shmparam.h> #include <asm/shmparam.h>
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
#include <asm/cacheflush.h>
#if SHMLBA > 16384 #if SHMLBA > 16384
#error FIX ME #error FIX ME
......
...@@ -158,7 +158,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm) ...@@ -158,7 +158,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
init_pgd = pgd_offset_k(0); init_pgd = pgd_offset_k(0);
if (vectors_base() == 0) { if (!vectors_high()) {
/* /*
* This lock is here just to satisfy pmd_alloc and pte_lock * This lock is here just to satisfy pmd_alloc and pte_lock
*/ */
...@@ -317,12 +317,18 @@ static struct mem_types mem_types[] __initdata = { ...@@ -317,12 +317,18 @@ static struct mem_types mem_types[] __initdata = {
.prot_sect = PMD_TYPE_SECT | PMD_SECT_MINICACHE, .prot_sect = PMD_TYPE_SECT | PMD_SECT_MINICACHE,
.domain = DOMAIN_KERNEL, .domain = DOMAIN_KERNEL,
}, },
[MT_VECTORS] = { [MT_LOW_VECTORS] = {
.prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
L_PTE_EXEC, L_PTE_EXEC,
.prot_l1 = PMD_TYPE_TABLE, .prot_l1 = PMD_TYPE_TABLE,
.domain = DOMAIN_USER, .domain = DOMAIN_USER,
}, },
[MT_HIGH_VECTORS] = {
.prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
L_PTE_USER | L_PTE_EXEC,
.prot_l1 = PMD_TYPE_TABLE,
.domain = DOMAIN_USER,
},
[MT_MEMORY] = { [MT_MEMORY] = {
.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
.domain = DOMAIN_KERNEL, .domain = DOMAIN_KERNEL,
...@@ -357,13 +363,12 @@ static void __init build_mem_type_table(void) ...@@ -357,13 +363,12 @@ static void __init build_mem_type_table(void)
} }
if (cpu_arch <= CPU_ARCH_ARMv5) { if (cpu_arch <= CPU_ARCH_ARMv5) {
mem_types[MT_DEVICE].prot_l1 |= PMD_BIT4; for (i = 0; i < ARRAY_SIZE(mem_types); i++) {
mem_types[MT_DEVICE].prot_sect |= PMD_BIT4; if (mem_types[i].prot_l1)
mem_types[MT_CACHECLEAN].prot_sect |= PMD_BIT4; mem_types[i].prot_l1 |= PMD_BIT4;
mem_types[MT_MINICLEAN].prot_sect |= PMD_BIT4; if (mem_types[i].prot_sect)
mem_types[MT_VECTORS].prot_l1 |= PMD_BIT4; mem_types[i].prot_sect |= PMD_BIT4;
mem_types[MT_MEMORY].prot_sect |= PMD_BIT4; }
mem_types[MT_ROM].prot_sect |= PMD_BIT4;
} }
/* /*
...@@ -387,13 +392,16 @@ static void __init build_mem_type_table(void) ...@@ -387,13 +392,16 @@ static void __init build_mem_type_table(void)
cp = &cache_policies[cachepolicy]; cp = &cache_policies[cachepolicy];
if (cpu_arch >= CPU_ARCH_ARMv5) { if (cpu_arch >= CPU_ARCH_ARMv5) {
mem_types[MT_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE; mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE;
mem_types[MT_HIGH_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE;
} else { } else {
mem_types[MT_VECTORS].prot_pte |= cp->pte; mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte;
mem_types[MT_HIGH_VECTORS].prot_pte |= cp->pte;
mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1); mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1);
} }
mem_types[MT_VECTORS].prot_l1 |= ecc_mask; mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask;
mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd; mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd;
mem_types[MT_ROM].prot_sect |= cp->pmd; mem_types[MT_ROM].prot_sect |= cp->pmd;
...@@ -420,6 +428,8 @@ static void __init build_mem_type_table(void) ...@@ -420,6 +428,8 @@ static void __init build_mem_type_table(void)
ecc_mask ? "en" : "dis", cp->policy); ecc_mask ? "en" : "dis", cp->policy);
} }
#define vectors_base() (vectors_high() ? 0xffff0000 : 0)
/* /*
* Create the page directory entries and any necessary * Create the page directory entries and any necessary
* page tables for the mapping specified by `md'. We * page tables for the mapping specified by `md'. We
...@@ -587,16 +597,22 @@ void __init memtable_init(struct meminfo *mi) ...@@ -587,16 +597,22 @@ void __init memtable_init(struct meminfo *mi)
} while (address != 0); } while (address != 0);
/* /*
* Create a mapping for the machine vectors at virtual address 0 * Create a mapping for the machine vectors at the high-vectors
* or 0xffff0000. We should always try the high mapping. * location (0xffff0000). If we aren't using high-vectors, also
* create a mapping at the low-vectors virtual address.
*/ */
init_maps->physical = virt_to_phys(init_maps); init_maps->physical = virt_to_phys(init_maps);
init_maps->virtual = vectors_base(); init_maps->virtual = 0xffff0000;
init_maps->length = PAGE_SIZE; init_maps->length = PAGE_SIZE;
init_maps->type = MT_VECTORS; init_maps->type = MT_HIGH_VECTORS;
create_mapping(init_maps); create_mapping(init_maps);
if (!vectors_high()) {
init_maps->virtual = 0;
init_maps->type = MT_LOW_VECTORS;
create_mapping(init_maps);
}
flush_cache_all(); flush_cache_all();
flush_tlb_all(); flush_tlb_all();
} }
......
...@@ -201,6 +201,11 @@ __v6_setup: ...@@ -201,6 +201,11 @@ __v6_setup:
mov r10, #0x1f @ domains 0, 1 = manager mov r10, #0x1f @ domains 0, 1 = manager
mcr p15, 0, r10, c3, c0, 0 @ load domain access register mcr p15, 0, r10, c3, c0, 0 @ load domain access register
mrc p15, 0, r0, c1, c0, 0 @ read control register mrc p15, 0, r0, c1, c0, 0 @ read control register
#ifdef CONFIG_VFP
mrc p15, 0, r10, c1, c0, 2
orr r10, r10, #(3 << 20)
mcr p15, 0, r10, c1, c0, 2 @ Enable full access to VFP
#endif
ldr r10, cr1_clear @ get mask for bits to clear ldr r10, cr1_clear @ get mask for bits to clear
bic r0, r0, r10 @ clear bits them bic r0, r0, r10 @ clear bits them
ldr r10, cr1_set @ get mask for bits to set ldr r10, cr1_set @ get mask for bits to set
......
...@@ -21,9 +21,10 @@ struct meminfo; ...@@ -21,9 +21,10 @@ struct meminfo;
#define MT_DEVICE 0 #define MT_DEVICE 0
#define MT_CACHECLEAN 1 #define MT_CACHECLEAN 1
#define MT_MINICLEAN 2 #define MT_MINICLEAN 2
#define MT_VECTORS 3 #define MT_LOW_VECTORS 3
#define MT_MEMORY 4 #define MT_HIGH_VECTORS 4
#define MT_ROM 5 #define MT_MEMORY 5
#define MT_ROM 6
extern void create_memmap_holes(struct meminfo *); extern void create_memmap_holes(struct meminfo *);
extern void memtable_init(struct meminfo *); extern void memtable_init(struct meminfo *);
......
...@@ -128,9 +128,9 @@ extern unsigned long cr_alignment; /* defined in entry-armv.S */ ...@@ -128,9 +128,9 @@ extern unsigned long cr_alignment; /* defined in entry-armv.S */
extern unsigned int user_debug; extern unsigned int user_debug;
#if __LINUX_ARM_ARCH__ >= 4 #if __LINUX_ARM_ARCH__ >= 4
#define vectors_base() ((cr_alignment & CR_V) ? 0xffff0000 : 0) #define vectors_high() (cr_alignment & CR_V)
#else #else
#define vectors_base() (0) #define vectors_high() (0)
#endif #endif
#define mb() __asm__ __volatile__ ("" : : : "memory") #define mb() __asm__ __volatile__ ("" : : : "memory")
......
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