aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-11-07 16:32:21 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-07 16:32:21 -0500
commit89de09a9ba9ce293228b1f1aa3c68b5af33a70ce (patch)
treea322cc361f13dade2aa84ace8c9278d86e459640 /arch/arm
parentdad2ad82c5f058367df79de022bd12d36afcd065 (diff)
parentf6db449ca312d33045907337b68de1f647cf0730 (diff)
Merge master.kernel.org:/home/rmk/linux-2.6-arm
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig4
-rw-r--r--arch/arm/mach-ixp2000/core.c35
-rw-r--r--arch/arm/mach-realview/Kconfig9
-rw-r--r--arch/arm/mach-realview/Makefile1
-rw-r--r--arch/arm/mach-realview/core.h1
-rw-r--r--arch/arm/mach-realview/headsmp.S39
-rw-r--r--arch/arm/mach-realview/platsmp.c195
-rw-r--r--arch/arm/mach-realview/realview_eb.c5
-rw-r--r--arch/arm/mm/mm-armv.c48
-rw-r--r--arch/arm/mm/proc-v6.S26
-rw-r--r--arch/arm/nwfpe/fpa11.h2
-rw-r--r--arch/arm/nwfpe/fpa11_cpdt.c10
-rw-r--r--arch/arm/nwfpe/fpopcode.c16
-rw-r--r--arch/arm/nwfpe/softfloat-specialize1
-rw-r--r--arch/arm/nwfpe/softfloat.c6
-rw-r--r--arch/arm/nwfpe/softfloat.h14
16 files changed, 358 insertions, 54 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 296bc03d1cf1..91d5ef3397be 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -324,7 +324,7 @@ menu "Kernel Features"
324 324
325config SMP 325config SMP
326 bool "Symmetric Multi-Processing (EXPERIMENTAL)" 326 bool "Symmetric Multi-Processing (EXPERIMENTAL)"
327 depends on EXPERIMENTAL && BROKEN #&& n 327 depends on EXPERIMENTAL && REALVIEW_MPCORE
328 help 328 help
329 This enables support for systems with more than one CPU. If you have 329 This enables support for systems with more than one CPU. If you have
330 a system with only one CPU, like most personal computers, say N. If 330 a system with only one CPU, like most personal computers, say N. If
@@ -585,7 +585,7 @@ config FPE_NWFPE
585 585
586config FPE_NWFPE_XP 586config FPE_NWFPE_XP
587 bool "Support extended precision" 587 bool "Support extended precision"
588 depends on FPE_NWFPE && !CPU_BIG_ENDIAN 588 depends on FPE_NWFPE
589 help 589 help
590 Say Y to include 80-bit support in the kernel floating-point 590 Say Y to include 80-bit support in the kernel floating-point
591 emulator. Otherwise, only 32 and 64-bit support is compiled in. 591 emulator. Otherwise, only 32 and 64-bit support is compiled in.
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
index df140962bb0f..6851abaf5524 100644
--- a/arch/arm/mach-ixp2000/core.c
+++ b/arch/arm/mach-ixp2000/core.c
@@ -84,63 +84,54 @@ static struct map_desc ixp2000_io_desc[] __initdata = {
84 .virtual = IXP2000_CAP_VIRT_BASE, 84 .virtual = IXP2000_CAP_VIRT_BASE,
85 .pfn = __phys_to_pfn(IXP2000_CAP_PHYS_BASE), 85 .pfn = __phys_to_pfn(IXP2000_CAP_PHYS_BASE),
86 .length = IXP2000_CAP_SIZE, 86 .length = IXP2000_CAP_SIZE,
87 .type = MT_DEVICE 87 .type = MT_IXP2000_DEVICE,
88 }, { 88 }, {
89 .virtual = IXP2000_INTCTL_VIRT_BASE, 89 .virtual = IXP2000_INTCTL_VIRT_BASE,
90 .pfn = __phys_to_pfn(IXP2000_INTCTL_PHYS_BASE), 90 .pfn = __phys_to_pfn(IXP2000_INTCTL_PHYS_BASE),
91 .length = IXP2000_INTCTL_SIZE, 91 .length = IXP2000_INTCTL_SIZE,
92 .type = MT_DEVICE 92 .type = MT_IXP2000_DEVICE,
93 }, { 93 }, {
94 .virtual = IXP2000_PCI_CREG_VIRT_BASE, 94 .virtual = IXP2000_PCI_CREG_VIRT_BASE,
95 .pfn = __phys_to_pfn(IXP2000_PCI_CREG_PHYS_BASE), 95 .pfn = __phys_to_pfn(IXP2000_PCI_CREG_PHYS_BASE),
96 .length = IXP2000_PCI_CREG_SIZE, 96 .length = IXP2000_PCI_CREG_SIZE,
97 .type = MT_DEVICE 97 .type = MT_IXP2000_DEVICE,
98 }, { 98 }, {
99 .virtual = IXP2000_PCI_CSR_VIRT_BASE, 99 .virtual = IXP2000_PCI_CSR_VIRT_BASE,
100 .pfn = __phys_to_pfn(IXP2000_PCI_CSR_PHYS_BASE), 100 .pfn = __phys_to_pfn(IXP2000_PCI_CSR_PHYS_BASE),
101 .length = IXP2000_PCI_CSR_SIZE, 101 .length = IXP2000_PCI_CSR_SIZE,
102 .type = MT_DEVICE 102 .type = MT_IXP2000_DEVICE,
103 }, { 103 }, {
104 .virtual = IXP2000_MSF_VIRT_BASE, 104 .virtual = IXP2000_MSF_VIRT_BASE,
105 .pfn = __phys_to_pfn(IXP2000_MSF_PHYS_BASE), 105 .pfn = __phys_to_pfn(IXP2000_MSF_PHYS_BASE),
106 .length = IXP2000_MSF_SIZE, 106 .length = IXP2000_MSF_SIZE,
107 .type = MT_DEVICE 107 .type = MT_IXP2000_DEVICE,
108 }, { 108 }, {
109 .virtual = IXP2000_PCI_IO_VIRT_BASE, 109 .virtual = IXP2000_PCI_IO_VIRT_BASE,
110 .pfn = __phys_to_pfn(IXP2000_PCI_IO_PHYS_BASE), 110 .pfn = __phys_to_pfn(IXP2000_PCI_IO_PHYS_BASE),
111 .length = IXP2000_PCI_IO_SIZE, 111 .length = IXP2000_PCI_IO_SIZE,
112 .type = MT_DEVICE 112 .type = MT_IXP2000_DEVICE,
113 }, { 113 }, {
114 .virtual = IXP2000_PCI_CFG0_VIRT_BASE, 114 .virtual = IXP2000_PCI_CFG0_VIRT_BASE,
115 .pfn = __phys_to_pfn(IXP2000_PCI_CFG0_PHYS_BASE), 115 .pfn = __phys_to_pfn(IXP2000_PCI_CFG0_PHYS_BASE),
116 .length = IXP2000_PCI_CFG0_SIZE, 116 .length = IXP2000_PCI_CFG0_SIZE,
117 .type = MT_DEVICE 117 .type = MT_IXP2000_DEVICE,
118 }, { 118 }, {
119 .virtual = IXP2000_PCI_CFG1_VIRT_BASE, 119 .virtual = IXP2000_PCI_CFG1_VIRT_BASE,
120 .pfn = __phys_to_pfn(IXP2000_PCI_CFG1_PHYS_BASE), 120 .pfn = __phys_to_pfn(IXP2000_PCI_CFG1_PHYS_BASE),
121 .length = IXP2000_PCI_CFG1_SIZE, 121 .length = IXP2000_PCI_CFG1_SIZE,
122 .type = MT_DEVICE 122 .type = MT_IXP2000_DEVICE,
123 } 123 }
124}; 124};
125 125
126void __init ixp2000_map_io(void) 126void __init ixp2000_map_io(void)
127{ 127{
128 extern unsigned int processor_id;
129
130 /* 128 /*
131 * On IXP2400 CPUs we need to use MT_IXP2000_DEVICE for 129 * On IXP2400 CPUs we need to use MT_IXP2000_DEVICE so that
132 * tweaking the PMDs so XCB=101. On IXP2800s we use the normal 130 * XCB=101 (to avoid triggering erratum #66), and given that
133 * PMD flags. 131 * this mode speeds up I/O accesses and we have write buffer
132 * flushes in the right places anyway, it doesn't hurt to use
133 * XCB=101 for all IXP2000s.
134 */ 134 */
135 if ((processor_id & 0xfffffff0) == 0x69054190) {
136 int i;
137
138 printk(KERN_INFO "Enabling IXP2400 erratum #66 workaround\n");
139
140 for(i=0;i<ARRAY_SIZE(ixp2000_io_desc);i++)
141 ixp2000_io_desc[i].type = MT_IXP2000_DEVICE;
142 }
143
144 iotable_init(ixp2000_io_desc, ARRAY_SIZE(ixp2000_io_desc)); 135 iotable_init(ixp2000_io_desc, ARRAY_SIZE(ixp2000_io_desc));
145 136
146 /* Set slowport to 8-bit mode. */ 137 /* Set slowport to 8-bit mode. */
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig
index 4b63dc9eabfe..129976866d47 100644
--- a/arch/arm/mach-realview/Kconfig
+++ b/arch/arm/mach-realview/Kconfig
@@ -8,4 +8,13 @@ config MACH_REALVIEW_EB
8 help 8 help
9 Include support for the ARM(R) RealView Emulation Baseboard platform. 9 Include support for the ARM(R) RealView Emulation Baseboard platform.
10 10
11config REALVIEW_MPCORE
12 bool "Support MPcore tile"
13 depends on MACH_REALVIEW_EB
14 help
15 Enable support for the MPCore tile on the Realview platform.
16 Since there are device address and interrupt differences, a
17 kernel built with this option enabled is not compatible with
18 other tiles.
19
11endmenu 20endmenu
diff --git a/arch/arm/mach-realview/Makefile b/arch/arm/mach-realview/Makefile
index 8d37ea1605fd..011a85c10627 100644
--- a/arch/arm/mach-realview/Makefile
+++ b/arch/arm/mach-realview/Makefile
@@ -4,3 +4,4 @@
4 4
5obj-y := core.o clock.o 5obj-y := core.o clock.o
6obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o 6obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o
7obj-$(CONFIG_SMP) += platsmp.o headsmp.o
diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h
index 575599db74db..d83e8bad2038 100644
--- a/arch/arm/mach-realview/core.h
+++ b/arch/arm/mach-realview/core.h
@@ -23,6 +23,7 @@
23#define __ASM_ARCH_REALVIEW_H 23#define __ASM_ARCH_REALVIEW_H
24 24
25#include <asm/hardware/amba.h> 25#include <asm/hardware/amba.h>
26#include <asm/leds.h>
26#include <asm/io.h> 27#include <asm/io.h>
27 28
28#define __io_address(n) __io(IO_ADDRESS(n)) 29#define __io_address(n) __io(IO_ADDRESS(n))
diff --git a/arch/arm/mach-realview/headsmp.S b/arch/arm/mach-realview/headsmp.S
new file mode 100644
index 000000000000..4075473cf68a
--- /dev/null
+++ b/arch/arm/mach-realview/headsmp.S
@@ -0,0 +1,39 @@
1/*
2 * linux/arch/arm/mach-realview/headsmp.S
3 *
4 * Copyright (c) 2003 ARM Limited
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/linkage.h>
12#include <linux/init.h>
13
14 __INIT
15
16/*
17 * Realview specific entry point for secondary CPUs. This provides
18 * a "holding pen" into which all secondary cores are held until we're
19 * ready for them to initialise.
20 */
21ENTRY(realview_secondary_startup)
22 mrc p15, 0, r0, c0, c0, 5
23 and r0, r0, #15
24 adr r4, 1f
25 ldmia r4, {r5, r6}
26 sub r4, r4, r5
27 add r6, r6, r4
28pen: ldr r7, [r6]
29 cmp r7, r0
30 bne pen
31
32 /*
33 * we've been released from the holding pen: secondary_stack
34 * should now contain the SVC stack for this core
35 */
36 b secondary_startup
37
381: .long .
39 .long pen_release
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
new file mode 100644
index 000000000000..9844644d0fb5
--- /dev/null
+++ b/arch/arm/mach-realview/platsmp.c
@@ -0,0 +1,195 @@
1/*
2 * linux/arch/arm/mach-realview/platsmp.c
3 *
4 * Copyright (C) 2002 ARM Ltd.
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/init.h>
12#include <linux/errno.h>
13#include <linux/delay.h>
14#include <linux/device.h>
15#include <linux/smp.h>
16
17#include <asm/cacheflush.h>
18#include <asm/hardware/arm_scu.h>
19#include <asm/hardware.h>
20
21#include "core.h"
22
23extern void realview_secondary_startup(void);
24
25/*
26 * control for which core is the next to come out of the secondary
27 * boot "holding pen"
28 */
29volatile int __cpuinitdata pen_release = -1;
30
31static unsigned int __init get_core_count(void)
32{
33 unsigned int ncores;
34
35 ncores = __raw_readl(IO_ADDRESS(REALVIEW_MPCORE_SCU_BASE) + SCU_CONFIG);
36
37 return (ncores & 0x03) + 1;
38}
39
40static DEFINE_SPINLOCK(boot_lock);
41
42void __cpuinit platform_secondary_init(unsigned int cpu)
43{
44 /*
45 * the primary core may have used a "cross call" soft interrupt
46 * to get this processor out of WFI in the BootMonitor - make
47 * sure that we are no longer being sent this soft interrupt
48 */
49 smp_cross_call_done(cpumask_of_cpu(cpu));
50
51 /*
52 * if any interrupts are already enabled for the primary
53 * core (e.g. timer irq), then they will not have been enabled
54 * for us: do so
55 */
56 gic_cpu_init(__io_address(REALVIEW_GIC_CPU_BASE));
57
58 /*
59 * let the primary processor know we're out of the
60 * pen, then head off into the C entry point
61 */
62 pen_release = -1;
63
64 /*
65 * Synchronise with the boot thread.
66 */
67 spin_lock(&boot_lock);
68 spin_unlock(&boot_lock);
69}
70
71int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
72{
73 unsigned long timeout;
74
75 /*
76 * set synchronisation state between this boot processor
77 * and the secondary one
78 */
79 spin_lock(&boot_lock);
80
81 /*
82 * The secondary processor is waiting to be released from
83 * the holding pen - release it, then wait for it to flag
84 * that it has been released by resetting pen_release.
85 *
86 * Note that "pen_release" is the hardware CPU ID, whereas
87 * "cpu" is Linux's internal ID.
88 */
89 pen_release = cpu;
90 flush_cache_all();
91
92 /*
93 * XXX
94 *
95 * This is a later addition to the booting protocol: the
96 * bootMonitor now puts secondary cores into WFI, so
97 * poke_milo() no longer gets the cores moving; we need
98 * to send a soft interrupt to wake the secondary core.
99 * Use smp_cross_call() for this, since there's little
100 * point duplicating the code here
101 */
102 smp_cross_call(cpumask_of_cpu(cpu));
103
104 timeout = jiffies + (1 * HZ);
105 while (time_before(jiffies, timeout)) {
106 if (pen_release == -1)
107 break;
108
109 udelay(10);
110 }
111
112 /*
113 * now the secondary core is starting up let it run its
114 * calibrations, then wait for it to finish
115 */
116 spin_unlock(&boot_lock);
117
118 return pen_release != -1 ? -ENOSYS : 0;
119}
120
121static void __init poke_milo(void)
122{
123 extern void secondary_startup(void);
124
125 /* nobody is to be released from the pen yet */
126 pen_release = -1;
127
128 /*
129 * write the address of secondary startup into the system-wide
130 * flags register, then clear the bottom two bits, which is what
131 * BootMonitor is waiting for
132 */
133#if 1
134#define REALVIEW_SYS_FLAGSS_OFFSET 0x30
135 __raw_writel(virt_to_phys(realview_secondary_startup),
136 (IO_ADDRESS(REALVIEW_SYS_BASE) +
137 REALVIEW_SYS_FLAGSS_OFFSET));
138#define REALVIEW_SYS_FLAGSC_OFFSET 0x34
139 __raw_writel(3,
140 (IO_ADDRESS(REALVIEW_SYS_BASE) +
141 REALVIEW_SYS_FLAGSC_OFFSET));
142#endif
143
144 mb();
145}
146
147void __init smp_prepare_cpus(unsigned int max_cpus)
148{
149 unsigned int ncores = get_core_count();
150 unsigned int cpu = smp_processor_id();
151 int i;
152
153 /* sanity check */
154 if (ncores == 0) {
155 printk(KERN_ERR
156 "Realview: strange CM count of 0? Default to 1\n");
157
158 ncores = 1;
159 }
160
161 if (ncores > NR_CPUS) {
162 printk(KERN_WARNING
163 "Realview: no. of cores (%d) greater than configured "
164 "maximum of %d - clipping\n",
165 ncores, NR_CPUS);
166 ncores = NR_CPUS;
167 }
168
169 smp_store_cpu_info(cpu);
170
171 /*
172 * are we trying to boot more cores than exist?
173 */
174 if (max_cpus > ncores)
175 max_cpus = ncores;
176
177 /*
178 * Initialise the possible/present maps.
179 * cpu_possible_map describes the set of CPUs which may be present
180 * cpu_present_map describes the set of CPUs populated
181 */
182 for (i = 0; i < max_cpus; i++) {
183 cpu_set(i, cpu_possible_map);
184 cpu_set(i, cpu_present_map);
185 }
186
187 /*
188 * Do we need any more CPUs? If so, then let them know where
189 * to start. Note that, on modern versions of MILO, the "poke"
190 * doesn't actually do anything until each individual core is
191 * sent a soft interrupt to get it out of WFI
192 */
193 if (max_cpus > 1)
194 poke_milo();
195}
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index 267bb07e39b7..7dc32503fdf2 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -136,6 +136,11 @@ static struct amba_device *amba_devs[] __initdata = {
136 136
137static void __init gic_init_irq(void) 137static void __init gic_init_irq(void)
138{ 138{
139#ifdef CONFIG_REALVIEW_MPCORE
140 writel(0x0000a05f, __io_address(REALVIEW_SYS_LOCK));
141 writel(0x008003c0, __io_address(REALVIEW_SYS_BASE) + 0xd8);
142 writel(0x00000000, __io_address(REALVIEW_SYS_LOCK));
143#endif
139 gic_dist_init(__io_address(REALVIEW_GIC_DIST_BASE)); 144 gic_dist_init(__io_address(REALVIEW_GIC_DIST_BASE));
140 gic_cpu_init(__io_address(REALVIEW_GIC_CPU_BASE)); 145 gic_cpu_init(__io_address(REALVIEW_GIC_CPU_BASE));
141} 146}
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index fb5b40289de2..9e50127be635 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -354,7 +354,7 @@ void __init build_mem_type_table(void)
354{ 354{
355 struct cachepolicy *cp; 355 struct cachepolicy *cp;
356 unsigned int cr = get_cr(); 356 unsigned int cr = get_cr();
357 unsigned int user_pgprot; 357 unsigned int user_pgprot, kern_pgprot;
358 int cpu_arch = cpu_architecture(); 358 int cpu_arch = cpu_architecture();
359 int i; 359 int i;
360 360
@@ -381,7 +381,7 @@ void __init build_mem_type_table(void)
381 } 381 }
382 382
383 cp = &cache_policies[cachepolicy]; 383 cp = &cache_policies[cachepolicy];
384 user_pgprot = cp->pte; 384 kern_pgprot = user_pgprot = cp->pte;
385 385
386 /* 386 /*
387 * ARMv6 and above have extended page tables. 387 * ARMv6 and above have extended page tables.
@@ -393,6 +393,7 @@ void __init build_mem_type_table(void)
393 */ 393 */
394 mem_types[MT_MEMORY].prot_sect &= ~PMD_BIT4; 394 mem_types[MT_MEMORY].prot_sect &= ~PMD_BIT4;
395 mem_types[MT_ROM].prot_sect &= ~PMD_BIT4; 395 mem_types[MT_ROM].prot_sect &= ~PMD_BIT4;
396
396 /* 397 /*
397 * Mark cache clean areas and XIP ROM read only 398 * Mark cache clean areas and XIP ROM read only
398 * from SVC mode and no access from userspace. 399 * from SVC mode and no access from userspace.
@@ -412,32 +413,47 @@ void __init build_mem_type_table(void)
412 * (iow, non-global) 413 * (iow, non-global)
413 */ 414 */
414 user_pgprot |= L_PTE_ASID; 415 user_pgprot |= L_PTE_ASID;
416
417#ifdef CONFIG_SMP
418 /*
419 * Mark memory with the "shared" attribute for SMP systems
420 */
421 user_pgprot |= L_PTE_SHARED;
422 kern_pgprot |= L_PTE_SHARED;
423 mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
424#endif
415 } 425 }
416 426
427 for (i = 0; i < 16; i++) {
428 unsigned long v = pgprot_val(protection_map[i]);
429 v = (v & ~(L_PTE_BUFFERABLE|L_PTE_CACHEABLE)) | user_pgprot;
430 protection_map[i] = __pgprot(v);
431 }
432
433 mem_types[MT_LOW_VECTORS].prot_pte |= kern_pgprot;
434 mem_types[MT_HIGH_VECTORS].prot_pte |= kern_pgprot;
435
417 if (cpu_arch >= CPU_ARCH_ARMv5) { 436 if (cpu_arch >= CPU_ARCH_ARMv5) {
418 mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE; 437#ifndef CONFIG_SMP
419 mem_types[MT_HIGH_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE; 438 /*
439 * Only use write-through for non-SMP systems
440 */
441 mem_types[MT_LOW_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE;
442 mem_types[MT_HIGH_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE;
443#endif
420 } else { 444 } else {
421 mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte;
422 mem_types[MT_HIGH_VECTORS].prot_pte |= cp->pte;
423 mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1); 445 mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1);
424 } 446 }
425 447
448 pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
449 L_PTE_DIRTY | L_PTE_WRITE |
450 L_PTE_EXEC | kern_pgprot);
451
426 mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask; 452 mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask;
427 mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; 453 mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
428 mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd; 454 mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd;
429 mem_types[MT_ROM].prot_sect |= cp->pmd; 455 mem_types[MT_ROM].prot_sect |= cp->pmd;
430 456
431 for (i = 0; i < 16; i++) {
432 unsigned long v = pgprot_val(protection_map[i]);
433 v = (v & ~(PTE_BUFFERABLE|PTE_CACHEABLE)) | user_pgprot;
434 protection_map[i] = __pgprot(v);
435 }
436
437 pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
438 L_PTE_DIRTY | L_PTE_WRITE |
439 L_PTE_EXEC | cp->pte);
440
441 switch (cp->pmd) { 457 switch (cp->pmd) {
442 case PMD_SECT_WT: 458 case PMD_SECT_WT:
443 mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT; 459 mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT;
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 9bb5fff406fb..92f3ca31b7b9 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -12,6 +12,7 @@
12#include <linux/linkage.h> 12#include <linux/linkage.h>
13#include <asm/assembler.h> 13#include <asm/assembler.h>
14#include <asm/asm-offsets.h> 14#include <asm/asm-offsets.h>
15#include <asm/hardware/arm_scu.h>
15#include <asm/procinfo.h> 16#include <asm/procinfo.h>
16#include <asm/pgtable.h> 17#include <asm/pgtable.h>
17 18
@@ -112,6 +113,9 @@ ENTRY(cpu_v6_dcache_clean_area)
112ENTRY(cpu_v6_switch_mm) 113ENTRY(cpu_v6_switch_mm)
113 mov r2, #0 114 mov r2, #0
114 ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id 115 ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id
116#ifdef CONFIG_SMP
117 orr r0, r0, #2 @ set shared pgtable
118#endif
115 mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB 119 mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB
116 mcr p15, 0, r2, c7, c10, 4 @ drain write buffer 120 mcr p15, 0, r2, c7, c10, 4 @ drain write buffer
117 mcr p15, 0, r0, c2, c0, 0 @ set TTB 0 121 mcr p15, 0, r0, c2, c0, 0 @ set TTB 0
@@ -140,7 +144,7 @@ ENTRY(cpu_v6_switch_mm)
140ENTRY(cpu_v6_set_pte) 144ENTRY(cpu_v6_set_pte)
141 str r1, [r0], #-2048 @ linux version 145 str r1, [r0], #-2048 @ linux version
142 146
143 bic r2, r1, #0x000007f0 147 bic r2, r1, #0x000003f0
144 bic r2, r2, #0x00000003 148 bic r2, r2, #0x00000003
145 orr r2, r2, #PTE_EXT_AP0 | 2 149 orr r2, r2, #PTE_EXT_AP0 | 2
146 150
@@ -191,6 +195,23 @@ cpu_v6_name:
191 * - cache type register is implemented 195 * - cache type register is implemented
192 */ 196 */
193__v6_setup: 197__v6_setup:
198#ifdef CONFIG_SMP
199 /* Set up the SCU on core 0 only */
200 mrc p15, 0, r0, c0, c0, 5 @ CPU core number
201 ands r0, r0, #15
202 moveq r0, #0x10000000 @ SCU_BASE
203 orreq r0, r0, #0x00100000
204 ldreq r5, [r0, #SCU_CTRL]
205 orreq r5, r5, #1
206 streq r5, [r0, #SCU_CTRL]
207
208#ifndef CONFIG_CPU_DCACHE_DISABLE
209 mrc p15, 0, r0, c1, c0, 1 @ Enable SMP/nAMP mode
210 orr r0, r0, #0x20
211 mcr p15, 0, r0, c1, c0, 1
212#endif
213#endif
214
194 mov r0, #0 215 mov r0, #0
195 mcr p15, 0, r0, c7, c14, 0 @ clean+invalidate D cache 216 mcr p15, 0, r0, c7, c14, 0 @ clean+invalidate D cache
196 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache 217 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
@@ -198,6 +219,9 @@ __v6_setup:
198 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer 219 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
199 mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs 220 mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs
200 mcr p15, 0, r0, c2, c0, 2 @ TTB control register 221 mcr p15, 0, r0, c2, c0, 2 @ TTB control register
222#ifdef CONFIG_SMP
223 orr r4, r4, #2 @ set shared pgtable
224#endif
201 mcr p15, 0, r4, c2, c0, 1 @ load TTB1 225 mcr p15, 0, r4, c2, c0, 1 @ load TTB1
202#ifdef CONFIG_VFP 226#ifdef CONFIG_VFP
203 mrc p15, 0, r0, c1, c0, 2 227 mrc p15, 0, r0, c1, c0, 2
diff --git a/arch/arm/nwfpe/fpa11.h b/arch/arm/nwfpe/fpa11.h
index 9677ae8448e8..da4c616b6c49 100644
--- a/arch/arm/nwfpe/fpa11.h
+++ b/arch/arm/nwfpe/fpa11.h
@@ -60,7 +60,7 @@ typedef union tagFPREG {
60#ifdef CONFIG_FPE_NWFPE_XP 60#ifdef CONFIG_FPE_NWFPE_XP
61 floatx80 fExtended; 61 floatx80 fExtended;
62#else 62#else
63 int padding[3]; 63 u32 padding[3];
64#endif 64#endif
65} FPREG; 65} FPREG;
66 66
diff --git a/arch/arm/nwfpe/fpa11_cpdt.c b/arch/arm/nwfpe/fpa11_cpdt.c
index b0db5cbcc3b1..32859fa8dcfc 100644
--- a/arch/arm/nwfpe/fpa11_cpdt.c
+++ b/arch/arm/nwfpe/fpa11_cpdt.c
@@ -59,8 +59,13 @@ static inline void loadExtended(const unsigned int Fn, const unsigned int __user
59 p = (unsigned int *) &fpa11->fpreg[Fn].fExtended; 59 p = (unsigned int *) &fpa11->fpreg[Fn].fExtended;
60 fpa11->fType[Fn] = typeExtended; 60 fpa11->fType[Fn] = typeExtended;
61 get_user(p[0], &pMem[0]); /* sign & exponent */ 61 get_user(p[0], &pMem[0]); /* sign & exponent */
62#ifdef __ARMEB__
63 get_user(p[1], &pMem[1]); /* ms bits */
64 get_user(p[2], &pMem[2]); /* ls bits */
65#else
62 get_user(p[1], &pMem[2]); /* ls bits */ 66 get_user(p[1], &pMem[2]); /* ls bits */
63 get_user(p[2], &pMem[1]); /* ms bits */ 67 get_user(p[2], &pMem[1]); /* ms bits */
68#endif
64} 69}
65#endif 70#endif
66 71
@@ -177,8 +182,13 @@ static inline void storeExtended(const unsigned int Fn, unsigned int __user *pMe
177 } 182 }
178 183
179 put_user(val.i[0], &pMem[0]); /* sign & exp */ 184 put_user(val.i[0], &pMem[0]); /* sign & exp */
185#ifdef __ARMEB__
186 put_user(val.i[1], &pMem[1]); /* msw */
187 put_user(val.i[2], &pMem[2]);
188#else
180 put_user(val.i[1], &pMem[2]); 189 put_user(val.i[1], &pMem[2]);
181 put_user(val.i[2], &pMem[1]); /* msw */ 190 put_user(val.i[2], &pMem[1]); /* msw */
191#endif
182} 192}
183#endif 193#endif
184 194
diff --git a/arch/arm/nwfpe/fpopcode.c b/arch/arm/nwfpe/fpopcode.c
index 4c9f5703148c..67ff2ab08ea0 100644
--- a/arch/arm/nwfpe/fpopcode.c
+++ b/arch/arm/nwfpe/fpopcode.c
@@ -29,14 +29,14 @@
29 29
30#ifdef CONFIG_FPE_NWFPE_XP 30#ifdef CONFIG_FPE_NWFPE_XP
31const floatx80 floatx80Constant[] = { 31const floatx80 floatx80Constant[] = {
32 {0x0000, 0x0000000000000000ULL}, /* extended 0.0 */ 32 { .high = 0x0000, .low = 0x0000000000000000ULL},/* extended 0.0 */
33 {0x3fff, 0x8000000000000000ULL}, /* extended 1.0 */ 33 { .high = 0x3fff, .low = 0x8000000000000000ULL},/* extended 1.0 */
34 {0x4000, 0x8000000000000000ULL}, /* extended 2.0 */ 34 { .high = 0x4000, .low = 0x8000000000000000ULL},/* extended 2.0 */
35 {0x4000, 0xc000000000000000ULL}, /* extended 3.0 */ 35 { .high = 0x4000, .low = 0xc000000000000000ULL},/* extended 3.0 */
36 {0x4001, 0x8000000000000000ULL}, /* extended 4.0 */ 36 { .high = 0x4001, .low = 0x8000000000000000ULL},/* extended 4.0 */
37 {0x4001, 0xa000000000000000ULL}, /* extended 5.0 */ 37 { .high = 0x4001, .low = 0xa000000000000000ULL},/* extended 5.0 */
38 {0x3ffe, 0x8000000000000000ULL}, /* extended 0.5 */ 38 { .high = 0x3ffe, .low = 0x8000000000000000ULL},/* extended 0.5 */
39 {0x4002, 0xa000000000000000ULL} /* extended 10.0 */ 39 { .high = 0x4002, .low = 0xa000000000000000ULL},/* extended 10.0 */
40}; 40};
41#endif 41#endif
42 42
diff --git a/arch/arm/nwfpe/softfloat-specialize b/arch/arm/nwfpe/softfloat-specialize
index acf409144763..d4a4c8e06635 100644
--- a/arch/arm/nwfpe/softfloat-specialize
+++ b/arch/arm/nwfpe/softfloat-specialize
@@ -332,6 +332,7 @@ static floatx80 commonNaNToFloatx80( commonNaNT a )
332 332
333 z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 ); 333 z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
334 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; 334 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
335 z.__padding = 0;
335 return z; 336 return z;
336 337
337} 338}
diff --git a/arch/arm/nwfpe/softfloat.c b/arch/arm/nwfpe/softfloat.c
index f9f049132a17..0f9656e482ba 100644
--- a/arch/arm/nwfpe/softfloat.c
+++ b/arch/arm/nwfpe/softfloat.c
@@ -531,6 +531,7 @@ INLINE floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig )
531 531
532 z.low = zSig; 532 z.low = zSig;
533 z.high = ( ( (bits16) zSign )<<15 ) + zExp; 533 z.high = ( ( (bits16) zSign )<<15 ) + zExp;
534 z.__padding = 0;
534 return z; 535 return z;
535 536
536} 537}
@@ -2831,6 +2832,7 @@ static floatx80 subFloatx80Sigs( struct roundingData *roundData, floatx80 a, flo
2831 roundData->exception |= float_flag_invalid; 2832 roundData->exception |= float_flag_invalid;
2832 z.low = floatx80_default_nan_low; 2833 z.low = floatx80_default_nan_low;
2833 z.high = floatx80_default_nan_high; 2834 z.high = floatx80_default_nan_high;
2835 z.__padding = 0;
2834 return z; 2836 return z;
2835 } 2837 }
2836 if ( aExp == 0 ) { 2838 if ( aExp == 0 ) {
@@ -2950,6 +2952,7 @@ floatx80 floatx80_mul( struct roundingData *roundData, floatx80 a, floatx80 b )
2950 roundData->exception |= float_flag_invalid; 2952 roundData->exception |= float_flag_invalid;
2951 z.low = floatx80_default_nan_low; 2953 z.low = floatx80_default_nan_low;
2952 z.high = floatx80_default_nan_high; 2954 z.high = floatx80_default_nan_high;
2955 z.__padding = 0;
2953 return z; 2956 return z;
2954 } 2957 }
2955 return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); 2958 return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
@@ -3015,6 +3018,7 @@ floatx80 floatx80_div( struct roundingData *roundData, floatx80 a, floatx80 b )
3015 roundData->exception |= float_flag_invalid; 3018 roundData->exception |= float_flag_invalid;
3016 z.low = floatx80_default_nan_low; 3019 z.low = floatx80_default_nan_low;
3017 z.high = floatx80_default_nan_high; 3020 z.high = floatx80_default_nan_high;
3021 z.__padding = 0;
3018 return z; 3022 return z;
3019 } 3023 }
3020 roundData->exception |= float_flag_divbyzero; 3024 roundData->exception |= float_flag_divbyzero;
@@ -3093,6 +3097,7 @@ floatx80 floatx80_rem( struct roundingData *roundData, floatx80 a, floatx80 b )
3093 roundData->exception |= float_flag_invalid; 3097 roundData->exception |= float_flag_invalid;
3094 z.low = floatx80_default_nan_low; 3098 z.low = floatx80_default_nan_low;
3095 z.high = floatx80_default_nan_high; 3099 z.high = floatx80_default_nan_high;
3100 z.__padding = 0;
3096 return z; 3101 return z;
3097 } 3102 }
3098 normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); 3103 normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
@@ -3184,6 +3189,7 @@ floatx80 floatx80_sqrt( struct roundingData *roundData, floatx80 a )
3184 roundData->exception |= float_flag_invalid; 3189 roundData->exception |= float_flag_invalid;
3185 z.low = floatx80_default_nan_low; 3190 z.low = floatx80_default_nan_low;
3186 z.high = floatx80_default_nan_high; 3191 z.high = floatx80_default_nan_high;
3192 z.__padding = 0;
3187 return z; 3193 return z;
3188 } 3194 }
3189 if ( aExp == 0 ) { 3195 if ( aExp == 0 ) {
diff --git a/arch/arm/nwfpe/softfloat.h b/arch/arm/nwfpe/softfloat.h
index 14151700b6b2..978c699673c6 100644
--- a/arch/arm/nwfpe/softfloat.h
+++ b/arch/arm/nwfpe/softfloat.h
@@ -51,11 +51,17 @@ input or output the `floatx80' type will be defined.
51Software IEC/IEEE floating-point types. 51Software IEC/IEEE floating-point types.
52------------------------------------------------------------------------------- 52-------------------------------------------------------------------------------
53*/ 53*/
54typedef unsigned long int float32; 54typedef u32 float32;
55typedef unsigned long long float64; 55typedef u64 float64;
56typedef struct { 56typedef struct {
57 unsigned short high; 57#ifdef __ARMEB__
58 unsigned long long low; 58 u16 __padding;
59 u16 high;
60#else
61 u16 high;
62 u16 __padding;
63#endif
64 u64 low;
59} floatx80; 65} floatx80;
60 66
61/* 67/*