diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-07 16:32:21 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-07 16:32:21 -0500 |
commit | 89de09a9ba9ce293228b1f1aa3c68b5af33a70ce (patch) | |
tree | a322cc361f13dade2aa84ace8c9278d86e459640 | |
parent | dad2ad82c5f058367df79de022bd12d36afcd065 (diff) | |
parent | f6db449ca312d33045907337b68de1f647cf0730 (diff) |
Merge master.kernel.org:/home/rmk/linux-2.6-arm
-rw-r--r-- | arch/arm/Kconfig | 4 | ||||
-rw-r--r-- | arch/arm/mach-ixp2000/core.c | 35 | ||||
-rw-r--r-- | arch/arm/mach-realview/Kconfig | 9 | ||||
-rw-r--r-- | arch/arm/mach-realview/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-realview/core.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-realview/headsmp.S | 39 | ||||
-rw-r--r-- | arch/arm/mach-realview/platsmp.c | 195 | ||||
-rw-r--r-- | arch/arm/mach-realview/realview_eb.c | 5 | ||||
-rw-r--r-- | arch/arm/mm/mm-armv.c | 48 | ||||
-rw-r--r-- | arch/arm/mm/proc-v6.S | 26 | ||||
-rw-r--r-- | arch/arm/nwfpe/fpa11.h | 2 | ||||
-rw-r--r-- | arch/arm/nwfpe/fpa11_cpdt.c | 10 | ||||
-rw-r--r-- | arch/arm/nwfpe/fpopcode.c | 16 | ||||
-rw-r--r-- | arch/arm/nwfpe/softfloat-specialize | 1 | ||||
-rw-r--r-- | arch/arm/nwfpe/softfloat.c | 6 | ||||
-rw-r--r-- | arch/arm/nwfpe/softfloat.h | 14 | ||||
-rw-r--r-- | include/asm-arm/arch-realview/entry-macro.S | 14 | ||||
-rw-r--r-- | include/asm-arm/arch-realview/platform.h | 56 | ||||
-rw-r--r-- | include/asm-arm/arch-realview/smp.h | 31 | ||||
-rw-r--r-- | include/asm-arm/hardware/arm_scu.h | 13 |
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 | ||
325 | config SMP | 325 | config 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 | ||
586 | config FPE_NWFPE_XP | 586 | config 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 | ||
126 | void __init ixp2000_map_io(void) | 126 | void __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 | ||
11 | config 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 | |||
11 | endmenu | 20 | endmenu |
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 | ||
5 | obj-y := core.o clock.o | 5 | obj-y := core.o clock.o |
6 | obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o | 6 | obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o |
7 | obj-$(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 | */ | ||
21 | ENTRY(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 | ||
28 | pen: 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 | |||
38 | 1: .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 | |||
23 | extern 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 | */ | ||
29 | volatile int __cpuinitdata pen_release = -1; | ||
30 | |||
31 | static 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 | |||
40 | static DEFINE_SPINLOCK(boot_lock); | ||
41 | |||
42 | void __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 | |||
71 | int __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 | |||
121 | static 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 | |||
147 | void __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 | ||
137 | static void __init gic_init_irq(void) | 137 | static 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) | |||
112 | ENTRY(cpu_v6_switch_mm) | 113 | ENTRY(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) | |||
140 | ENTRY(cpu_v6_set_pte) | 144 | ENTRY(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 |
31 | const floatx80 floatx80Constant[] = { | 31 | const 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. | |||
51 | Software IEC/IEEE floating-point types. | 51 | Software IEC/IEEE floating-point types. |
52 | ------------------------------------------------------------------------------- | 52 | ------------------------------------------------------------------------------- |
53 | */ | 53 | */ |
54 | typedef unsigned long int float32; | 54 | typedef u32 float32; |
55 | typedef unsigned long long float64; | 55 | typedef u64 float64; |
56 | typedef struct { | 56 | typedef 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 | */ | ||
19 | static inline void smp_cross_call(cpumask_t callmap) | ||
20 | { | ||
21 | gic_raise_softirq(callmap, 1); | ||
22 | } | ||
23 | |||
24 | /* | ||
25 | * Do nothing on MPcore. | ||
26 | */ | ||
27 | static 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 | ||