aboutsummaryrefslogtreecommitdiffstats
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
parentdad2ad82c5f058367df79de022bd12d36afcd065 (diff)
parentf6db449ca312d33045907337b68de1f647cf0730 (diff)
Merge master.kernel.org:/home/rmk/linux-2.6-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
-rw-r--r--include/asm-arm/arch-realview/entry-macro.S14
-rw-r--r--include/asm-arm/arch-realview/platform.h56
-rw-r--r--include/asm-arm/arch-realview/smp.h31
-rw-r--r--include/asm-arm/hardware/arm_scu.h13
20 files changed, 472 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/*
diff --git a/include/asm-arm/arch-realview/entry-macro.S b/include/asm-arm/arch-realview/entry-macro.S
index 2712ba77bb3a..4df469bf42e2 100644
--- a/include/asm-arm/arch-realview/entry-macro.S
+++ b/include/asm-arm/arch-realview/entry-macro.S
@@ -47,3 +47,17 @@
47 cmpcs \irqnr, \irqnr 47 cmpcs \irqnr, \irqnr
48 48
49 .endm 49 .endm
50
51 /* We assume that irqstat (the raw value of the IRQ acknowledge
52 * register) is preserved from the macro above.
53 * If there is an IPI, we immediately signal end of interrupt on the
54 * controller, since this requires the original irqstat value which
55 * we won't easily be able to recreate later.
56 */
57
58 .macro test_for_ipi, irqnr, irqstat, base, tmp
59 bic \irqnr, \irqstat, #0x1c00
60 cmp \irqnr, #16
61 strcc \irqstat, [\base, #GIC_CPU_EOI]
62 cmpcs \irqnr, \irqnr
63 .endm
diff --git a/include/asm-arm/arch-realview/platform.h b/include/asm-arm/arch-realview/platform.h
index 4b6de13a6b9a..aef9b36b3c37 100644
--- a/include/asm-arm/arch-realview/platform.h
+++ b/include/asm-arm/arch-realview/platform.h
@@ -203,8 +203,14 @@
203 /* Reserved 0x1001A000 - 0x1001FFFF */ 203 /* Reserved 0x1001A000 - 0x1001FFFF */
204#define REALVIEW_CLCD_BASE 0x10020000 /* CLCD */ 204#define REALVIEW_CLCD_BASE 0x10020000 /* CLCD */
205#define REALVIEW_DMAC_BASE 0x10030000 /* DMA controller */ 205#define REALVIEW_DMAC_BASE 0x10030000 /* DMA controller */
206#ifndef CONFIG_REALVIEW_MPCORE
206#define REALVIEW_GIC_CPU_BASE 0x10040000 /* Generic interrupt controller CPU interface */ 207#define REALVIEW_GIC_CPU_BASE 0x10040000 /* Generic interrupt controller CPU interface */
207#define REALVIEW_GIC_DIST_BASE 0x10041000 /* Generic interrupt controller distributor */ 208#define REALVIEW_GIC_DIST_BASE 0x10041000 /* Generic interrupt controller distributor */
209#else
210#define REALVIEW_MPCORE_SCU_BASE 0x10100000 /* SCU registers */
211#define REALVIEW_GIC_CPU_BASE 0x10100100 /* Generic interrupt controller CPU interface */
212#define REALVIEW_GIC_DIST_BASE 0x10101000 /* Generic interrupt controller distributor */
213#endif
208#define REALVIEW_SMC_BASE 0x10080000 /* SMC */ 214#define REALVIEW_SMC_BASE 0x10080000 /* SMC */
209 /* Reserved 0x10090000 - 0x100EFFFF */ 215 /* Reserved 0x10090000 - 0x100EFFFF */
210 216
@@ -265,6 +271,7 @@
265 * Interrupts - bit assignment (primary) 271 * Interrupts - bit assignment (primary)
266 * ------------------------------------------------------------------------ 272 * ------------------------------------------------------------------------
267 */ 273 */
274#ifndef CONFIG_REALVIEW_MPCORE
268#define INT_WDOGINT 0 /* Watchdog timer */ 275#define INT_WDOGINT 0 /* Watchdog timer */
269#define INT_SOFTINT 1 /* Software interrupt */ 276#define INT_SOFTINT 1 /* Software interrupt */
270#define INT_COMMRx 2 /* Debug Comm Rx interrupt */ 277#define INT_COMMRx 2 /* Debug Comm Rx interrupt */
@@ -297,6 +304,55 @@
297#define INT_USB 29 /* USB controller */ 304#define INT_USB 29 /* USB controller */
298#define INT_TSPENINT 30 /* Touchscreen pen */ 305#define INT_TSPENINT 30 /* Touchscreen pen */
299#define INT_TSKPADINT 31 /* Touchscreen keypad */ 306#define INT_TSKPADINT 31 /* Touchscreen keypad */
307#else
308#define INT_LOCALTIMER 29
309#define INT_LOCALWDOG 30
310
311#define INT_AACI 0
312#define INT_TIMERINT0_1 1
313#define INT_TIMERINT2_3 2
314#define INT_USB 3
315#define INT_UARTINT0 4
316#define INT_UARTINT1 5
317#define INT_RTCINT 6
318#define INT_KMI0 7
319#define INT_KMI1 8
320#define INT_ETH 9
321#define INT_EB_IRQ1 10 /* main GIC */
322#define INT_EB_IRQ2 11 /* tile GIC */
323#define INT_EB_FIQ1 12 /* main GIC */
324#define INT_EB_FIQ2 13 /* tile GIC */
325#define INT_MMCI0A 14
326#define INT_MMCI0B 15
327
328#define INT_PMU_CPU0 17
329#define INT_PMU_CPU1 18
330#define INT_PMU_CPU2 19
331#define INT_PMU_CPU3 20
332#define INT_PMU_SCU0 21
333#define INT_PMU_SCU1 22
334#define INT_PMU_SCU2 23
335#define INT_PMU_SCU3 24
336#define INT_PMU_SCU4 25
337#define INT_PMU_SCU5 26
338#define INT_PMU_SCU6 27
339#define INT_PMU_SCU7 28
340
341#define INT_L220_EVENT 29
342#define INT_L220_SLAVE 30
343#define INT_L220_DECODE 31
344
345#define INT_UARTINT2 -1
346#define INT_UARTINT3 -1
347#define INT_CLCDINT -1
348#define INT_DMAINT -1
349#define INT_WDOGINT -1
350#define INT_GPIOINT0 -1
351#define INT_GPIOINT1 -1
352#define INT_GPIOINT2 -1
353#define INT_SCIINT -1
354#define INT_SSPINT -1
355#endif
300 356
301/* 357/*
302 * Interrupt bit positions 358 * Interrupt bit positions
diff --git a/include/asm-arm/arch-realview/smp.h b/include/asm-arm/arch-realview/smp.h
new file mode 100644
index 000000000000..fc87783e8e8b
--- /dev/null
+++ b/include/asm-arm/arch-realview/smp.h
@@ -0,0 +1,31 @@
1#ifndef ASMARM_ARCH_SMP_H
2#define ASMARM_ARCH_SMP_H
3
4#include <linux/config.h>
5
6#include <asm/hardware/gic.h>
7
8#define hard_smp_processor_id() \
9 ({ \
10 unsigned int cpunum; \
11 __asm__("mrc p15, 0, %0, c0, c0, 5" \
12 : "=r" (cpunum)); \
13 cpunum &= 0x0F; \
14 })
15
16/*
17 * We use IRQ1 as the IPI
18 */
19static inline void smp_cross_call(cpumask_t callmap)
20{
21 gic_raise_softirq(callmap, 1);
22}
23
24/*
25 * Do nothing on MPcore.
26 */
27static inline void smp_cross_call_done(cpumask_t callmap)
28{
29}
30
31#endif
diff --git a/include/asm-arm/hardware/arm_scu.h b/include/asm-arm/hardware/arm_scu.h
new file mode 100644
index 000000000000..9903f60c84b7
--- /dev/null
+++ b/include/asm-arm/hardware/arm_scu.h
@@ -0,0 +1,13 @@
1#ifndef ASMARM_HARDWARE_ARM_SCU_H
2#define ASMARM_HARDWARE_ARM_SCU_H
3
4/*
5 * SCU registers
6 */
7#define SCU_CTRL 0x00
8#define SCU_CONFIG 0x04
9#define SCU_CPU_STATUS 0x08
10#define SCU_INVALIDATE 0x0c
11#define SCU_FPGA_REVISION 0x10
12
13#endif