diff options
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r-- | arch/mips/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/mips/kernel/binfmt_elfn32.c | 11 | ||||
-rw-r--r-- | arch/mips/kernel/binfmt_elfo32.c | 11 | ||||
-rw-r--r-- | arch/mips/kernel/cpu-probe.c | 198 | ||||
-rw-r--r-- | arch/mips/kernel/crash_dump.c | 1 | ||||
-rw-r--r-- | arch/mips/kernel/ftrace.c | 4 | ||||
-rw-r--r-- | arch/mips/kernel/genex.S | 8 | ||||
-rw-r--r-- | arch/mips/kernel/idle.c | 245 | ||||
-rw-r--r-- | arch/mips/kernel/kprobes.c | 5 | ||||
-rw-r--r-- | arch/mips/kernel/proc.c | 1 | ||||
-rw-r--r-- | arch/mips/kernel/process.c | 53 | ||||
-rw-r--r-- | arch/mips/kernel/rtlx.c | 1 | ||||
-rw-r--r-- | arch/mips/kernel/scall64-64.S | 1 | ||||
-rw-r--r-- | arch/mips/kernel/smp.c | 1 | ||||
-rw-r--r-- | arch/mips/kernel/smtc.c | 15 | ||||
-rw-r--r-- | arch/mips/kernel/traps.c | 43 |
16 files changed, 349 insertions, 251 deletions
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 6ad9e04bdf62..423d871a946b 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | extra-y := head.o vmlinux.lds | 5 | extra-y := head.o vmlinux.lds |
6 | 6 | ||
7 | obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ | 7 | obj-y += cpu-probe.o branch.o entry.o genex.o idle.o irq.o process.o \ |
8 | prom.o ptrace.o reset.o setup.o signal.o syscall.o \ | 8 | prom.o ptrace.o reset.o setup.o signal.o syscall.o \ |
9 | time.o topology.o traps.o unaligned.o watch.o vdso.o | 9 | time.o topology.o traps.o unaligned.o watch.o vdso.o |
10 | 10 | ||
diff --git a/arch/mips/kernel/binfmt_elfn32.c b/arch/mips/kernel/binfmt_elfn32.c index e06f777e9c49..1188e00bb120 100644 --- a/arch/mips/kernel/binfmt_elfn32.c +++ b/arch/mips/kernel/binfmt_elfn32.c | |||
@@ -119,4 +119,15 @@ MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)"); | |||
119 | #undef TASK_SIZE | 119 | #undef TASK_SIZE |
120 | #define TASK_SIZE TASK_SIZE32 | 120 | #define TASK_SIZE TASK_SIZE32 |
121 | 121 | ||
122 | #undef cputime_to_timeval | ||
123 | #define cputime_to_timeval cputime_to_compat_timeval | ||
124 | static __inline__ void | ||
125 | cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value) | ||
126 | { | ||
127 | unsigned long jiffies = cputime_to_jiffies(cputime); | ||
128 | |||
129 | value->tv_usec = (jiffies % HZ) * (1000000L / HZ); | ||
130 | value->tv_sec = jiffies / HZ; | ||
131 | } | ||
132 | |||
122 | #include "../../../fs/binfmt_elf.c" | 133 | #include "../../../fs/binfmt_elf.c" |
diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c index 97c5a1668e53..202e581e6096 100644 --- a/arch/mips/kernel/binfmt_elfo32.c +++ b/arch/mips/kernel/binfmt_elfo32.c | |||
@@ -162,4 +162,15 @@ MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)"); | |||
162 | #undef TASK_SIZE | 162 | #undef TASK_SIZE |
163 | #define TASK_SIZE TASK_SIZE32 | 163 | #define TASK_SIZE TASK_SIZE32 |
164 | 164 | ||
165 | #undef cputime_to_timeval | ||
166 | #define cputime_to_timeval cputime_to_compat_timeval | ||
167 | static __inline__ void | ||
168 | cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value) | ||
169 | { | ||
170 | unsigned long jiffies = cputime_to_jiffies(cputime); | ||
171 | |||
172 | value->tv_usec = (jiffies % HZ) * (1000000L / HZ); | ||
173 | value->tv_sec = jiffies / HZ; | ||
174 | } | ||
175 | |||
165 | #include "../../../fs/binfmt_elf.c" | 176 | #include "../../../fs/binfmt_elf.c" |
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 4bbffdb9024f..c6568bf4b1b0 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
@@ -27,105 +27,6 @@ | |||
27 | #include <asm/spram.h> | 27 | #include <asm/spram.h> |
28 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
29 | 29 | ||
30 | /* | ||
31 | * Not all of the MIPS CPUs have the "wait" instruction available. Moreover, | ||
32 | * the implementation of the "wait" feature differs between CPU families. This | ||
33 | * points to the function that implements CPU specific wait. | ||
34 | * The wait instruction stops the pipeline and reduces the power consumption of | ||
35 | * the CPU very much. | ||
36 | */ | ||
37 | void (*cpu_wait)(void); | ||
38 | EXPORT_SYMBOL(cpu_wait); | ||
39 | |||
40 | static void r3081_wait(void) | ||
41 | { | ||
42 | unsigned long cfg = read_c0_conf(); | ||
43 | write_c0_conf(cfg | R30XX_CONF_HALT); | ||
44 | } | ||
45 | |||
46 | static void r39xx_wait(void) | ||
47 | { | ||
48 | local_irq_disable(); | ||
49 | if (!need_resched()) | ||
50 | write_c0_conf(read_c0_conf() | TX39_CONF_HALT); | ||
51 | local_irq_enable(); | ||
52 | } | ||
53 | |||
54 | extern void r4k_wait(void); | ||
55 | |||
56 | /* | ||
57 | * This variant is preferable as it allows testing need_resched and going to | ||
58 | * sleep depending on the outcome atomically. Unfortunately the "It is | ||
59 | * implementation-dependent whether the pipeline restarts when a non-enabled | ||
60 | * interrupt is requested" restriction in the MIPS32/MIPS64 architecture makes | ||
61 | * using this version a gamble. | ||
62 | */ | ||
63 | void r4k_wait_irqoff(void) | ||
64 | { | ||
65 | local_irq_disable(); | ||
66 | if (!need_resched()) | ||
67 | __asm__(" .set push \n" | ||
68 | " .set mips3 \n" | ||
69 | " wait \n" | ||
70 | " .set pop \n"); | ||
71 | local_irq_enable(); | ||
72 | __asm__(" .globl __pastwait \n" | ||
73 | "__pastwait: \n"); | ||
74 | } | ||
75 | |||
76 | /* | ||
77 | * The RM7000 variant has to handle erratum 38. The workaround is to not | ||
78 | * have any pending stores when the WAIT instruction is executed. | ||
79 | */ | ||
80 | static void rm7k_wait_irqoff(void) | ||
81 | { | ||
82 | local_irq_disable(); | ||
83 | if (!need_resched()) | ||
84 | __asm__( | ||
85 | " .set push \n" | ||
86 | " .set mips3 \n" | ||
87 | " .set noat \n" | ||
88 | " mfc0 $1, $12 \n" | ||
89 | " sync \n" | ||
90 | " mtc0 $1, $12 # stalls until W stage \n" | ||
91 | " wait \n" | ||
92 | " mtc0 $1, $12 # stalls until W stage \n" | ||
93 | " .set pop \n"); | ||
94 | local_irq_enable(); | ||
95 | } | ||
96 | |||
97 | /* | ||
98 | * The Au1xxx wait is available only if using 32khz counter or | ||
99 | * external timer source, but specifically not CP0 Counter. | ||
100 | * alchemy/common/time.c may override cpu_wait! | ||
101 | */ | ||
102 | static void au1k_wait(void) | ||
103 | { | ||
104 | __asm__(" .set mips3 \n" | ||
105 | " cache 0x14, 0(%0) \n" | ||
106 | " cache 0x14, 32(%0) \n" | ||
107 | " sync \n" | ||
108 | " nop \n" | ||
109 | " wait \n" | ||
110 | " nop \n" | ||
111 | " nop \n" | ||
112 | " nop \n" | ||
113 | " nop \n" | ||
114 | " .set mips0 \n" | ||
115 | : : "r" (au1k_wait)); | ||
116 | } | ||
117 | |||
118 | static int __initdata nowait; | ||
119 | |||
120 | static int __init wait_disable(char *s) | ||
121 | { | ||
122 | nowait = 1; | ||
123 | |||
124 | return 1; | ||
125 | } | ||
126 | |||
127 | __setup("nowait", wait_disable); | ||
128 | |||
129 | static int __cpuinitdata mips_fpu_disabled; | 30 | static int __cpuinitdata mips_fpu_disabled; |
130 | 31 | ||
131 | static int __init fpu_disable(char *s) | 32 | static int __init fpu_disable(char *s) |
@@ -150,105 +51,6 @@ static int __init dsp_disable(char *s) | |||
150 | 51 | ||
151 | __setup("nodsp", dsp_disable); | 52 | __setup("nodsp", dsp_disable); |
152 | 53 | ||
153 | void __init check_wait(void) | ||
154 | { | ||
155 | struct cpuinfo_mips *c = ¤t_cpu_data; | ||
156 | |||
157 | if (nowait) { | ||
158 | printk("Wait instruction disabled.\n"); | ||
159 | return; | ||
160 | } | ||
161 | |||
162 | switch (c->cputype) { | ||
163 | case CPU_R3081: | ||
164 | case CPU_R3081E: | ||
165 | cpu_wait = r3081_wait; | ||
166 | break; | ||
167 | case CPU_TX3927: | ||
168 | cpu_wait = r39xx_wait; | ||
169 | break; | ||
170 | case CPU_R4200: | ||
171 | /* case CPU_R4300: */ | ||
172 | case CPU_R4600: | ||
173 | case CPU_R4640: | ||
174 | case CPU_R4650: | ||
175 | case CPU_R4700: | ||
176 | case CPU_R5000: | ||
177 | case CPU_R5500: | ||
178 | case CPU_NEVADA: | ||
179 | case CPU_4KC: | ||
180 | case CPU_4KEC: | ||
181 | case CPU_4KSC: | ||
182 | case CPU_5KC: | ||
183 | case CPU_25KF: | ||
184 | case CPU_PR4450: | ||
185 | case CPU_BMIPS3300: | ||
186 | case CPU_BMIPS4350: | ||
187 | case CPU_BMIPS4380: | ||
188 | case CPU_BMIPS5000: | ||
189 | case CPU_CAVIUM_OCTEON: | ||
190 | case CPU_CAVIUM_OCTEON_PLUS: | ||
191 | case CPU_CAVIUM_OCTEON2: | ||
192 | case CPU_JZRISC: | ||
193 | case CPU_LOONGSON1: | ||
194 | case CPU_XLR: | ||
195 | case CPU_XLP: | ||
196 | cpu_wait = r4k_wait; | ||
197 | break; | ||
198 | |||
199 | case CPU_RM7000: | ||
200 | cpu_wait = rm7k_wait_irqoff; | ||
201 | break; | ||
202 | |||
203 | case CPU_M14KC: | ||
204 | case CPU_M14KEC: | ||
205 | case CPU_24K: | ||
206 | case CPU_34K: | ||
207 | case CPU_1004K: | ||
208 | cpu_wait = r4k_wait; | ||
209 | if (read_c0_config7() & MIPS_CONF7_WII) | ||
210 | cpu_wait = r4k_wait_irqoff; | ||
211 | break; | ||
212 | |||
213 | case CPU_74K: | ||
214 | cpu_wait = r4k_wait; | ||
215 | if ((c->processor_id & 0xff) >= PRID_REV_ENCODE_332(2, 1, 0)) | ||
216 | cpu_wait = r4k_wait_irqoff; | ||
217 | break; | ||
218 | |||
219 | case CPU_TX49XX: | ||
220 | cpu_wait = r4k_wait_irqoff; | ||
221 | break; | ||
222 | case CPU_ALCHEMY: | ||
223 | cpu_wait = au1k_wait; | ||
224 | break; | ||
225 | case CPU_20KC: | ||
226 | /* | ||
227 | * WAIT on Rev1.0 has E1, E2, E3 and E16. | ||
228 | * WAIT on Rev2.0 and Rev3.0 has E16. | ||
229 | * Rev3.1 WAIT is nop, why bother | ||
230 | */ | ||
231 | if ((c->processor_id & 0xff) <= 0x64) | ||
232 | break; | ||
233 | |||
234 | /* | ||
235 | * Another rev is incremeting c0_count at a reduced clock | ||
236 | * rate while in WAIT mode. So we basically have the choice | ||
237 | * between using the cp0 timer as clocksource or avoiding | ||
238 | * the WAIT instruction. Until more details are known, | ||
239 | * disable the use of WAIT for 20Kc entirely. | ||
240 | cpu_wait = r4k_wait; | ||
241 | */ | ||
242 | break; | ||
243 | case CPU_RM9000: | ||
244 | if ((c->processor_id & 0x00ff) >= 0x40) | ||
245 | cpu_wait = r4k_wait; | ||
246 | break; | ||
247 | default: | ||
248 | break; | ||
249 | } | ||
250 | } | ||
251 | |||
252 | static inline void check_errata(void) | 54 | static inline void check_errata(void) |
253 | { | 55 | { |
254 | struct cpuinfo_mips *c = ¤t_cpu_data; | 56 | struct cpuinfo_mips *c = ¤t_cpu_data; |
diff --git a/arch/mips/kernel/crash_dump.c b/arch/mips/kernel/crash_dump.c index 35bed0d2342c..3be9e7bb30ff 100644 --- a/arch/mips/kernel/crash_dump.c +++ b/arch/mips/kernel/crash_dump.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <linux/bootmem.h> | 2 | #include <linux/bootmem.h> |
3 | #include <linux/crash_dump.h> | 3 | #include <linux/crash_dump.h> |
4 | #include <asm/uaccess.h> | 4 | #include <asm/uaccess.h> |
5 | #include <linux/slab.h> | ||
5 | 6 | ||
6 | static int __init parse_savemaxmem(char *p) | 7 | static int __init parse_savemaxmem(char *p) |
7 | { | 8 | { |
diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c index cf5509f13dd5..dba90ec0dc38 100644 --- a/arch/mips/kernel/ftrace.c +++ b/arch/mips/kernel/ftrace.c | |||
@@ -25,12 +25,16 @@ | |||
25 | #define MCOUNT_OFFSET_INSNS 4 | 25 | #define MCOUNT_OFFSET_INSNS 4 |
26 | #endif | 26 | #endif |
27 | 27 | ||
28 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
29 | |||
28 | /* Arch override because MIPS doesn't need to run this from stop_machine() */ | 30 | /* Arch override because MIPS doesn't need to run this from stop_machine() */ |
29 | void arch_ftrace_update_code(int command) | 31 | void arch_ftrace_update_code(int command) |
30 | { | 32 | { |
31 | ftrace_modify_all_code(command); | 33 | ftrace_modify_all_code(command); |
32 | } | 34 | } |
33 | 35 | ||
36 | #endif | ||
37 | |||
34 | /* | 38 | /* |
35 | * Check if the address is in kernel space | 39 | * Check if the address is in kernel space |
36 | * | 40 | * |
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index 5c2ba9f08a80..31fa856829cb 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S | |||
@@ -122,7 +122,7 @@ handle_vcei: | |||
122 | __FINIT | 122 | __FINIT |
123 | 123 | ||
124 | .align 5 /* 32 byte rollback region */ | 124 | .align 5 /* 32 byte rollback region */ |
125 | LEAF(r4k_wait) | 125 | LEAF(__r4k_wait) |
126 | .set push | 126 | .set push |
127 | .set noreorder | 127 | .set noreorder |
128 | /* start of rollback region */ | 128 | /* start of rollback region */ |
@@ -146,14 +146,14 @@ LEAF(r4k_wait) | |||
146 | jr ra | 146 | jr ra |
147 | nop | 147 | nop |
148 | .set pop | 148 | .set pop |
149 | END(r4k_wait) | 149 | END(__r4k_wait) |
150 | 150 | ||
151 | .macro BUILD_ROLLBACK_PROLOGUE handler | 151 | .macro BUILD_ROLLBACK_PROLOGUE handler |
152 | FEXPORT(rollback_\handler) | 152 | FEXPORT(rollback_\handler) |
153 | .set push | 153 | .set push |
154 | .set noat | 154 | .set noat |
155 | MFC0 k0, CP0_EPC | 155 | MFC0 k0, CP0_EPC |
156 | PTR_LA k1, r4k_wait | 156 | PTR_LA k1, __r4k_wait |
157 | ori k0, 0x1f /* 32 byte rollback region */ | 157 | ori k0, 0x1f /* 32 byte rollback region */ |
158 | xori k0, 0x1f | 158 | xori k0, 0x1f |
159 | bne k0, k1, 9f | 159 | bne k0, k1, 9f |
@@ -493,7 +493,7 @@ NESTED(nmi_handler, PT_SIZE, sp) | |||
493 | .set noreorder | 493 | .set noreorder |
494 | /* check if TLB contains a entry for EPC */ | 494 | /* check if TLB contains a entry for EPC */ |
495 | MFC0 k1, CP0_ENTRYHI | 495 | MFC0 k1, CP0_ENTRYHI |
496 | andi k1, 0xff /* ASID_MASK patched at run-time!! */ | 496 | andi k1, 0xff /* ASID_MASK */ |
497 | MFC0 k0, CP0_EPC | 497 | MFC0 k0, CP0_EPC |
498 | PTR_SRL k0, _PAGE_SHIFT + 1 | 498 | PTR_SRL k0, _PAGE_SHIFT + 1 |
499 | PTR_SLL k0, _PAGE_SHIFT + 1 | 499 | PTR_SLL k0, _PAGE_SHIFT + 1 |
diff --git a/arch/mips/kernel/idle.c b/arch/mips/kernel/idle.c new file mode 100644 index 000000000000..0c655deeea4a --- /dev/null +++ b/arch/mips/kernel/idle.c | |||
@@ -0,0 +1,245 @@ | |||
1 | /* | ||
2 | * MIPS idle loop and WAIT instruction support. | ||
3 | * | ||
4 | * Copyright (C) xxxx the Anonymous | ||
5 | * Copyright (C) 1994 - 2006 Ralf Baechle | ||
6 | * Copyright (C) 2003, 2004 Maciej W. Rozycki | ||
7 | * Copyright (C) 2001, 2004, 2011, 2012 MIPS Technologies, Inc. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * as published by the Free Software Foundation; either version | ||
12 | * 2 of the License, or (at your option) any later version. | ||
13 | */ | ||
14 | #include <linux/export.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/irqflags.h> | ||
17 | #include <linux/printk.h> | ||
18 | #include <linux/sched.h> | ||
19 | #include <asm/cpu.h> | ||
20 | #include <asm/cpu-info.h> | ||
21 | #include <asm/idle.h> | ||
22 | #include <asm/mipsregs.h> | ||
23 | |||
24 | /* | ||
25 | * Not all of the MIPS CPUs have the "wait" instruction available. Moreover, | ||
26 | * the implementation of the "wait" feature differs between CPU families. This | ||
27 | * points to the function that implements CPU specific wait. | ||
28 | * The wait instruction stops the pipeline and reduces the power consumption of | ||
29 | * the CPU very much. | ||
30 | */ | ||
31 | void (*cpu_wait)(void); | ||
32 | EXPORT_SYMBOL(cpu_wait); | ||
33 | |||
34 | static void r3081_wait(void) | ||
35 | { | ||
36 | unsigned long cfg = read_c0_conf(); | ||
37 | write_c0_conf(cfg | R30XX_CONF_HALT); | ||
38 | local_irq_enable(); | ||
39 | } | ||
40 | |||
41 | static void r39xx_wait(void) | ||
42 | { | ||
43 | if (!need_resched()) | ||
44 | write_c0_conf(read_c0_conf() | TX39_CONF_HALT); | ||
45 | local_irq_enable(); | ||
46 | } | ||
47 | |||
48 | void r4k_wait(void) | ||
49 | { | ||
50 | local_irq_enable(); | ||
51 | __r4k_wait(); | ||
52 | } | ||
53 | |||
54 | /* | ||
55 | * This variant is preferable as it allows testing need_resched and going to | ||
56 | * sleep depending on the outcome atomically. Unfortunately the "It is | ||
57 | * implementation-dependent whether the pipeline restarts when a non-enabled | ||
58 | * interrupt is requested" restriction in the MIPS32/MIPS64 architecture makes | ||
59 | * using this version a gamble. | ||
60 | */ | ||
61 | void r4k_wait_irqoff(void) | ||
62 | { | ||
63 | if (!need_resched()) | ||
64 | __asm__( | ||
65 | " .set push \n" | ||
66 | " .set mips3 \n" | ||
67 | " wait \n" | ||
68 | " .set pop \n"); | ||
69 | local_irq_enable(); | ||
70 | __asm__( | ||
71 | " .globl __pastwait \n" | ||
72 | "__pastwait: \n"); | ||
73 | } | ||
74 | |||
75 | /* | ||
76 | * The RM7000 variant has to handle erratum 38. The workaround is to not | ||
77 | * have any pending stores when the WAIT instruction is executed. | ||
78 | */ | ||
79 | static void rm7k_wait_irqoff(void) | ||
80 | { | ||
81 | if (!need_resched()) | ||
82 | __asm__( | ||
83 | " .set push \n" | ||
84 | " .set mips3 \n" | ||
85 | " .set noat \n" | ||
86 | " mfc0 $1, $12 \n" | ||
87 | " sync \n" | ||
88 | " mtc0 $1, $12 # stalls until W stage \n" | ||
89 | " wait \n" | ||
90 | " mtc0 $1, $12 # stalls until W stage \n" | ||
91 | " .set pop \n"); | ||
92 | local_irq_enable(); | ||
93 | } | ||
94 | |||
95 | /* | ||
96 | * Au1 'wait' is only useful when the 32kHz counter is used as timer, | ||
97 | * since coreclock (and the cp0 counter) stops upon executing it. Only an | ||
98 | * interrupt can wake it, so they must be enabled before entering idle modes. | ||
99 | */ | ||
100 | static void au1k_wait(void) | ||
101 | { | ||
102 | unsigned long c0status = read_c0_status() | 1; /* irqs on */ | ||
103 | |||
104 | __asm__( | ||
105 | " .set mips3 \n" | ||
106 | " cache 0x14, 0(%0) \n" | ||
107 | " cache 0x14, 32(%0) \n" | ||
108 | " sync \n" | ||
109 | " mtc0 %1, $12 \n" /* wr c0status */ | ||
110 | " wait \n" | ||
111 | " nop \n" | ||
112 | " nop \n" | ||
113 | " nop \n" | ||
114 | " nop \n" | ||
115 | " .set mips0 \n" | ||
116 | : : "r" (au1k_wait), "r" (c0status)); | ||
117 | } | ||
118 | |||
119 | static int __initdata nowait; | ||
120 | |||
121 | static int __init wait_disable(char *s) | ||
122 | { | ||
123 | nowait = 1; | ||
124 | |||
125 | return 1; | ||
126 | } | ||
127 | |||
128 | __setup("nowait", wait_disable); | ||
129 | |||
130 | void __init check_wait(void) | ||
131 | { | ||
132 | struct cpuinfo_mips *c = ¤t_cpu_data; | ||
133 | |||
134 | if (nowait) { | ||
135 | printk("Wait instruction disabled.\n"); | ||
136 | return; | ||
137 | } | ||
138 | |||
139 | switch (c->cputype) { | ||
140 | case CPU_R3081: | ||
141 | case CPU_R3081E: | ||
142 | cpu_wait = r3081_wait; | ||
143 | break; | ||
144 | case CPU_TX3927: | ||
145 | cpu_wait = r39xx_wait; | ||
146 | break; | ||
147 | case CPU_R4200: | ||
148 | /* case CPU_R4300: */ | ||
149 | case CPU_R4600: | ||
150 | case CPU_R4640: | ||
151 | case CPU_R4650: | ||
152 | case CPU_R4700: | ||
153 | case CPU_R5000: | ||
154 | case CPU_R5500: | ||
155 | case CPU_NEVADA: | ||
156 | case CPU_4KC: | ||
157 | case CPU_4KEC: | ||
158 | case CPU_4KSC: | ||
159 | case CPU_5KC: | ||
160 | case CPU_25KF: | ||
161 | case CPU_PR4450: | ||
162 | case CPU_BMIPS3300: | ||
163 | case CPU_BMIPS4350: | ||
164 | case CPU_BMIPS4380: | ||
165 | case CPU_BMIPS5000: | ||
166 | case CPU_CAVIUM_OCTEON: | ||
167 | case CPU_CAVIUM_OCTEON_PLUS: | ||
168 | case CPU_CAVIUM_OCTEON2: | ||
169 | case CPU_JZRISC: | ||
170 | case CPU_LOONGSON1: | ||
171 | case CPU_XLR: | ||
172 | case CPU_XLP: | ||
173 | cpu_wait = r4k_wait; | ||
174 | break; | ||
175 | |||
176 | case CPU_RM7000: | ||
177 | cpu_wait = rm7k_wait_irqoff; | ||
178 | break; | ||
179 | |||
180 | case CPU_M14KC: | ||
181 | case CPU_M14KEC: | ||
182 | case CPU_24K: | ||
183 | case CPU_34K: | ||
184 | case CPU_1004K: | ||
185 | cpu_wait = r4k_wait; | ||
186 | if (read_c0_config7() & MIPS_CONF7_WII) | ||
187 | cpu_wait = r4k_wait_irqoff; | ||
188 | break; | ||
189 | |||
190 | case CPU_74K: | ||
191 | cpu_wait = r4k_wait; | ||
192 | if ((c->processor_id & 0xff) >= PRID_REV_ENCODE_332(2, 1, 0)) | ||
193 | cpu_wait = r4k_wait_irqoff; | ||
194 | break; | ||
195 | |||
196 | case CPU_TX49XX: | ||
197 | cpu_wait = r4k_wait_irqoff; | ||
198 | break; | ||
199 | case CPU_ALCHEMY: | ||
200 | cpu_wait = au1k_wait; | ||
201 | break; | ||
202 | case CPU_20KC: | ||
203 | /* | ||
204 | * WAIT on Rev1.0 has E1, E2, E3 and E16. | ||
205 | * WAIT on Rev2.0 and Rev3.0 has E16. | ||
206 | * Rev3.1 WAIT is nop, why bother | ||
207 | */ | ||
208 | if ((c->processor_id & 0xff) <= 0x64) | ||
209 | break; | ||
210 | |||
211 | /* | ||
212 | * Another rev is incremeting c0_count at a reduced clock | ||
213 | * rate while in WAIT mode. So we basically have the choice | ||
214 | * between using the cp0 timer as clocksource or avoiding | ||
215 | * the WAIT instruction. Until more details are known, | ||
216 | * disable the use of WAIT for 20Kc entirely. | ||
217 | cpu_wait = r4k_wait; | ||
218 | */ | ||
219 | break; | ||
220 | case CPU_RM9000: | ||
221 | if ((c->processor_id & 0x00ff) >= 0x40) | ||
222 | cpu_wait = r4k_wait; | ||
223 | break; | ||
224 | default: | ||
225 | break; | ||
226 | } | ||
227 | } | ||
228 | |||
229 | static void smtc_idle_hook(void) | ||
230 | { | ||
231 | #ifdef CONFIG_MIPS_MT_SMTC | ||
232 | void smtc_idle_loop_hook(void); | ||
233 | |||
234 | smtc_idle_loop_hook(); | ||
235 | #endif | ||
236 | } | ||
237 | |||
238 | void arch_cpu_idle(void) | ||
239 | { | ||
240 | smtc_idle_hook(); | ||
241 | if (cpu_wait) | ||
242 | cpu_wait(); | ||
243 | else | ||
244 | local_irq_enable(); | ||
245 | } | ||
diff --git a/arch/mips/kernel/kprobes.c b/arch/mips/kernel/kprobes.c index 12bc4ebdf55b..1f8187ab0997 100644 --- a/arch/mips/kernel/kprobes.c +++ b/arch/mips/kernel/kprobes.c | |||
@@ -207,7 +207,10 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p) | |||
207 | 207 | ||
208 | void __kprobes arch_remove_kprobe(struct kprobe *p) | 208 | void __kprobes arch_remove_kprobe(struct kprobe *p) |
209 | { | 209 | { |
210 | free_insn_slot(p->ainsn.insn, 0); | 210 | if (p->ainsn.insn) { |
211 | free_insn_slot(p->ainsn.insn, 0); | ||
212 | p->ainsn.insn = NULL; | ||
213 | } | ||
211 | } | 214 | } |
212 | 215 | ||
213 | static void save_previous_kprobe(struct kprobe_ctlblk *kcb) | 216 | static void save_previous_kprobe(struct kprobe_ctlblk *kcb) |
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index a3e461408b7e..acb34373679e 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <asm/bootinfo.h> | 10 | #include <asm/bootinfo.h> |
11 | #include <asm/cpu.h> | 11 | #include <asm/cpu.h> |
12 | #include <asm/cpu-features.h> | 12 | #include <asm/cpu-features.h> |
13 | #include <asm/idle.h> | ||
13 | #include <asm/mipsregs.h> | 14 | #include <asm/mipsregs.h> |
14 | #include <asm/processor.h> | 15 | #include <asm/processor.h> |
15 | #include <asm/prom.h> | 16 | #include <asm/prom.h> |
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index eb902c1f0cad..c6a041d9d05d 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c | |||
@@ -51,19 +51,6 @@ void arch_cpu_idle_dead(void) | |||
51 | } | 51 | } |
52 | #endif | 52 | #endif |
53 | 53 | ||
54 | void arch_cpu_idle(void) | ||
55 | { | ||
56 | #ifdef CONFIG_MIPS_MT_SMTC | ||
57 | extern void smtc_idle_loop_hook(void); | ||
58 | |||
59 | smtc_idle_loop_hook(); | ||
60 | #endif | ||
61 | if (cpu_wait) | ||
62 | (*cpu_wait)(); | ||
63 | else | ||
64 | local_irq_enable(); | ||
65 | } | ||
66 | |||
67 | asmlinkage void ret_from_fork(void); | 54 | asmlinkage void ret_from_fork(void); |
68 | asmlinkage void ret_from_kernel_thread(void); | 55 | asmlinkage void ret_from_kernel_thread(void); |
69 | 56 | ||
@@ -224,6 +211,9 @@ struct mips_frame_info { | |||
224 | int pc_offset; | 211 | int pc_offset; |
225 | }; | 212 | }; |
226 | 213 | ||
214 | #define J_TARGET(pc,target) \ | ||
215 | (((unsigned long)(pc) & 0xf0000000) | ((target) << 2)) | ||
216 | |||
227 | static inline int is_ra_save_ins(union mips_instruction *ip) | 217 | static inline int is_ra_save_ins(union mips_instruction *ip) |
228 | { | 218 | { |
229 | #ifdef CONFIG_CPU_MICROMIPS | 219 | #ifdef CONFIG_CPU_MICROMIPS |
@@ -264,7 +254,7 @@ static inline int is_ra_save_ins(union mips_instruction *ip) | |||
264 | #endif | 254 | #endif |
265 | } | 255 | } |
266 | 256 | ||
267 | static inline int is_jal_jalr_jr_ins(union mips_instruction *ip) | 257 | static inline int is_jump_ins(union mips_instruction *ip) |
268 | { | 258 | { |
269 | #ifdef CONFIG_CPU_MICROMIPS | 259 | #ifdef CONFIG_CPU_MICROMIPS |
270 | /* | 260 | /* |
@@ -288,6 +278,8 @@ static inline int is_jal_jalr_jr_ins(union mips_instruction *ip) | |||
288 | return 0; | 278 | return 0; |
289 | return (((ip->u_format.uimmediate >> 6) & mm_jalr_op) == mm_jalr_op); | 279 | return (((ip->u_format.uimmediate >> 6) & mm_jalr_op) == mm_jalr_op); |
290 | #else | 280 | #else |
281 | if (ip->j_format.opcode == j_op) | ||
282 | return 1; | ||
291 | if (ip->j_format.opcode == jal_op) | 283 | if (ip->j_format.opcode == jal_op) |
292 | return 1; | 284 | return 1; |
293 | if (ip->r_format.opcode != spec_op) | 285 | if (ip->r_format.opcode != spec_op) |
@@ -350,7 +342,7 @@ static int get_frame_info(struct mips_frame_info *info) | |||
350 | 342 | ||
351 | for (i = 0; i < max_insns; i++, ip++) { | 343 | for (i = 0; i < max_insns; i++, ip++) { |
352 | 344 | ||
353 | if (is_jal_jalr_jr_ins(ip)) | 345 | if (is_jump_ins(ip)) |
354 | break; | 346 | break; |
355 | if (!info->frame_size) { | 347 | if (!info->frame_size) { |
356 | if (is_sp_move_ins(ip)) | 348 | if (is_sp_move_ins(ip)) |
@@ -393,15 +385,42 @@ err: | |||
393 | 385 | ||
394 | static struct mips_frame_info schedule_mfi __read_mostly; | 386 | static struct mips_frame_info schedule_mfi __read_mostly; |
395 | 387 | ||
388 | #ifdef CONFIG_KALLSYMS | ||
389 | static unsigned long get___schedule_addr(void) | ||
390 | { | ||
391 | return kallsyms_lookup_name("__schedule"); | ||
392 | } | ||
393 | #else | ||
394 | static unsigned long get___schedule_addr(void) | ||
395 | { | ||
396 | union mips_instruction *ip = (void *)schedule; | ||
397 | int max_insns = 8; | ||
398 | int i; | ||
399 | |||
400 | for (i = 0; i < max_insns; i++, ip++) { | ||
401 | if (ip->j_format.opcode == j_op) | ||
402 | return J_TARGET(ip, ip->j_format.target); | ||
403 | } | ||
404 | return 0; | ||
405 | } | ||
406 | #endif | ||
407 | |||
396 | static int __init frame_info_init(void) | 408 | static int __init frame_info_init(void) |
397 | { | 409 | { |
398 | unsigned long size = 0; | 410 | unsigned long size = 0; |
399 | #ifdef CONFIG_KALLSYMS | 411 | #ifdef CONFIG_KALLSYMS |
400 | unsigned long ofs; | 412 | unsigned long ofs; |
413 | #endif | ||
414 | unsigned long addr; | ||
415 | |||
416 | addr = get___schedule_addr(); | ||
417 | if (!addr) | ||
418 | addr = (unsigned long)schedule; | ||
401 | 419 | ||
402 | kallsyms_lookup_size_offset((unsigned long)schedule, &size, &ofs); | 420 | #ifdef CONFIG_KALLSYMS |
421 | kallsyms_lookup_size_offset(addr, &size, &ofs); | ||
403 | #endif | 422 | #endif |
404 | schedule_mfi.func = schedule; | 423 | schedule_mfi.func = (void *)addr; |
405 | schedule_mfi.func_size = size; | 424 | schedule_mfi.func_size = size; |
406 | 425 | ||
407 | get_frame_info(&schedule_mfi); | 426 | get_frame_info(&schedule_mfi); |
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c index 93c070b41b0d..6fa198db8999 100644 --- a/arch/mips/kernel/rtlx.c +++ b/arch/mips/kernel/rtlx.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <asm/processor.h> | 40 | #include <asm/processor.h> |
41 | #include <asm/vpe.h> | 41 | #include <asm/vpe.h> |
42 | #include <asm/rtlx.h> | 42 | #include <asm/rtlx.h> |
43 | #include <asm/setup.h> | ||
43 | 44 | ||
44 | static struct rtlx_info *rtlx; | 45 | static struct rtlx_info *rtlx; |
45 | static int major; | 46 | static int major; |
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 36cfd4060e1f..97a5909a61cf 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S | |||
@@ -423,4 +423,5 @@ sys_call_table: | |||
423 | PTR sys_process_vm_writev /* 5305 */ | 423 | PTR sys_process_vm_writev /* 5305 */ |
424 | PTR sys_kcmp | 424 | PTR sys_kcmp |
425 | PTR sys_finit_module | 425 | PTR sys_finit_module |
426 | PTR sys_getdents64 | ||
426 | .size sys_call_table,.-sys_call_table | 427 | .size sys_call_table,.-sys_call_table |
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index c17619fe18e3..6e7862ab46cc 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/atomic.h> | 37 | #include <linux/atomic.h> |
38 | #include <asm/cpu.h> | 38 | #include <asm/cpu.h> |
39 | #include <asm/processor.h> | 39 | #include <asm/processor.h> |
40 | #include <asm/idle.h> | ||
40 | #include <asm/r4k-timer.h> | 41 | #include <asm/r4k-timer.h> |
41 | #include <asm/mmu_context.h> | 42 | #include <asm/mmu_context.h> |
42 | #include <asm/time.h> | 43 | #include <asm/time.h> |
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index 31d22f3121c9..75a4fd709841 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <asm/hardirq.h> | 34 | #include <asm/hardirq.h> |
35 | #include <asm/hazards.h> | 35 | #include <asm/hazards.h> |
36 | #include <asm/irq.h> | 36 | #include <asm/irq.h> |
37 | #include <asm/idle.h> | ||
37 | #include <asm/mmu_context.h> | 38 | #include <asm/mmu_context.h> |
38 | #include <asm/mipsregs.h> | 39 | #include <asm/mipsregs.h> |
39 | #include <asm/cacheflush.h> | 40 | #include <asm/cacheflush.h> |
@@ -111,7 +112,7 @@ static int vpe0limit; | |||
111 | static int ipibuffers; | 112 | static int ipibuffers; |
112 | static int nostlb; | 113 | static int nostlb; |
113 | static int asidmask; | 114 | static int asidmask; |
114 | unsigned int smtc_asid_mask = 0xff; | 115 | unsigned long smtc_asid_mask = 0xff; |
115 | 116 | ||
116 | static int __init vpe0tcs(char *str) | 117 | static int __init vpe0tcs(char *str) |
117 | { | 118 | { |
@@ -858,7 +859,6 @@ void smtc_send_ipi(int cpu, int type, unsigned int action) | |||
858 | unsigned long flags; | 859 | unsigned long flags; |
859 | int mtflags; | 860 | int mtflags; |
860 | unsigned long tcrestart; | 861 | unsigned long tcrestart; |
861 | extern void r4k_wait_irqoff(void), __pastwait(void); | ||
862 | int set_resched_flag = (type == LINUX_SMP_IPI && | 862 | int set_resched_flag = (type == LINUX_SMP_IPI && |
863 | action == SMP_RESCHEDULE_YOURSELF); | 863 | action == SMP_RESCHEDULE_YOURSELF); |
864 | 864 | ||
@@ -914,8 +914,7 @@ void smtc_send_ipi(int cpu, int type, unsigned int action) | |||
914 | */ | 914 | */ |
915 | if (cpu_wait == r4k_wait_irqoff) { | 915 | if (cpu_wait == r4k_wait_irqoff) { |
916 | tcrestart = read_tc_c0_tcrestart(); | 916 | tcrestart = read_tc_c0_tcrestart(); |
917 | if (tcrestart >= (unsigned long)r4k_wait_irqoff | 917 | if (address_is_in_r4k_wait_irqoff(tcrestart)) { |
918 | && tcrestart < (unsigned long)__pastwait) { | ||
919 | write_tc_c0_tcrestart(__pastwait); | 918 | write_tc_c0_tcrestart(__pastwait); |
920 | tcstatus &= ~TCSTATUS_IXMT; | 919 | tcstatus &= ~TCSTATUS_IXMT; |
921 | write_tc_c0_tcstatus(tcstatus); | 920 | write_tc_c0_tcstatus(tcstatus); |
@@ -1395,7 +1394,7 @@ void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) | |||
1395 | asid = asid_cache(cpu); | 1394 | asid = asid_cache(cpu); |
1396 | 1395 | ||
1397 | do { | 1396 | do { |
1398 | if (!ASID_MASK(ASID_INC(asid))) { | 1397 | if (!((asid += ASID_INC) & ASID_MASK) ) { |
1399 | if (cpu_has_vtag_icache) | 1398 | if (cpu_has_vtag_icache) |
1400 | flush_icache_all(); | 1399 | flush_icache_all(); |
1401 | /* Traverse all online CPUs (hack requires contiguous range) */ | 1400 | /* Traverse all online CPUs (hack requires contiguous range) */ |
@@ -1414,7 +1413,7 @@ void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) | |||
1414 | mips_ihb(); | 1413 | mips_ihb(); |
1415 | } | 1414 | } |
1416 | tcstat = read_tc_c0_tcstatus(); | 1415 | tcstat = read_tc_c0_tcstatus(); |
1417 | smtc_live_asid[tlb][ASID_MASK(tcstat)] |= (asiduse)(0x1 << i); | 1416 | smtc_live_asid[tlb][(tcstat & ASID_MASK)] |= (asiduse)(0x1 << i); |
1418 | if (!prevhalt) | 1417 | if (!prevhalt) |
1419 | write_tc_c0_tchalt(0); | 1418 | write_tc_c0_tchalt(0); |
1420 | } | 1419 | } |
@@ -1423,7 +1422,7 @@ void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) | |||
1423 | asid = ASID_FIRST_VERSION; | 1422 | asid = ASID_FIRST_VERSION; |
1424 | local_flush_tlb_all(); /* start new asid cycle */ | 1423 | local_flush_tlb_all(); /* start new asid cycle */ |
1425 | } | 1424 | } |
1426 | } while (smtc_live_asid[tlb][ASID_MASK(asid)]); | 1425 | } while (smtc_live_asid[tlb][(asid & ASID_MASK)]); |
1427 | 1426 | ||
1428 | /* | 1427 | /* |
1429 | * SMTC shares the TLB within VPEs and possibly across all VPEs. | 1428 | * SMTC shares the TLB within VPEs and possibly across all VPEs. |
@@ -1461,7 +1460,7 @@ void smtc_flush_tlb_asid(unsigned long asid) | |||
1461 | tlb_read(); | 1460 | tlb_read(); |
1462 | ehb(); | 1461 | ehb(); |
1463 | ehi = read_c0_entryhi(); | 1462 | ehi = read_c0_entryhi(); |
1464 | if (ASID_MASK(ehi) == asid) { | 1463 | if ((ehi & ASID_MASK) == asid) { |
1465 | /* | 1464 | /* |
1466 | * Invalidate only entries with specified ASID, | 1465 | * Invalidate only entries with specified ASID, |
1467 | * makiing sure all entries differ. | 1466 | * makiing sure all entries differ. |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 77cff1f6d050..a75ae40184aa 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <asm/dsp.h> | 41 | #include <asm/dsp.h> |
42 | #include <asm/fpu.h> | 42 | #include <asm/fpu.h> |
43 | #include <asm/fpu_emulator.h> | 43 | #include <asm/fpu_emulator.h> |
44 | #include <asm/idle.h> | ||
44 | #include <asm/mipsregs.h> | 45 | #include <asm/mipsregs.h> |
45 | #include <asm/mipsmtregs.h> | 46 | #include <asm/mipsmtregs.h> |
46 | #include <asm/module.h> | 47 | #include <asm/module.h> |
@@ -57,7 +58,6 @@ | |||
57 | #include <asm/uasm.h> | 58 | #include <asm/uasm.h> |
58 | 59 | ||
59 | extern void check_wait(void); | 60 | extern void check_wait(void); |
60 | extern asmlinkage void r4k_wait(void); | ||
61 | extern asmlinkage void rollback_handle_int(void); | 61 | extern asmlinkage void rollback_handle_int(void); |
62 | extern asmlinkage void handle_int(void); | 62 | extern asmlinkage void handle_int(void); |
63 | extern u32 handle_tlbl[]; | 63 | extern u32 handle_tlbl[]; |
@@ -897,22 +897,24 @@ out_sigsegv: | |||
897 | 897 | ||
898 | asmlinkage void do_tr(struct pt_regs *regs) | 898 | asmlinkage void do_tr(struct pt_regs *regs) |
899 | { | 899 | { |
900 | unsigned int opcode, tcode = 0; | 900 | u32 opcode, tcode = 0; |
901 | u16 instr[2]; | 901 | u16 instr[2]; |
902 | unsigned long epc = exception_epc(regs); | 902 | unsigned long epc = msk_isa16_mode(exception_epc(regs)); |
903 | 903 | ||
904 | if ((__get_user(instr[0], (u16 __user *)msk_isa16_mode(epc))) || | 904 | if (get_isa16_mode(regs->cp0_epc)) { |
905 | (__get_user(instr[1], (u16 __user *)msk_isa16_mode(epc + 2)))) | 905 | if (__get_user(instr[0], (u16 __user *)(epc + 0)) || |
906 | __get_user(instr[1], (u16 __user *)(epc + 2))) | ||
906 | goto out_sigsegv; | 907 | goto out_sigsegv; |
907 | opcode = (instr[0] << 16) | instr[1]; | 908 | opcode = (instr[0] << 16) | instr[1]; |
908 | 909 | /* Immediate versions don't provide a code. */ | |
909 | /* Immediate versions don't provide a code. */ | 910 | if (!(opcode & OPCODE)) |
910 | if (!(opcode & OPCODE)) { | 911 | tcode = (opcode >> 12) & ((1 << 4) - 1); |
911 | if (get_isa16_mode(regs->cp0_epc)) | 912 | } else { |
912 | /* microMIPS */ | 913 | if (__get_user(opcode, (u32 __user *)epc)) |
913 | tcode = (opcode >> 12) & 0x1f; | 914 | goto out_sigsegv; |
914 | else | 915 | /* Immediate versions don't provide a code. */ |
915 | tcode = ((opcode >> 6) & ((1 << 10) - 1)); | 916 | if (!(opcode & OPCODE)) |
917 | tcode = (opcode >> 6) & ((1 << 10) - 1); | ||
916 | } | 918 | } |
917 | 919 | ||
918 | do_trap_or_bp(regs, tcode, "Trap"); | 920 | do_trap_or_bp(regs, tcode, "Trap"); |
@@ -1542,7 +1544,7 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) | |||
1542 | extern char except_vec_vi, except_vec_vi_lui; | 1544 | extern char except_vec_vi, except_vec_vi_lui; |
1543 | extern char except_vec_vi_ori, except_vec_vi_end; | 1545 | extern char except_vec_vi_ori, except_vec_vi_end; |
1544 | extern char rollback_except_vec_vi; | 1546 | extern char rollback_except_vec_vi; |
1545 | char *vec_start = (cpu_wait == r4k_wait) ? | 1547 | char *vec_start = using_rollback_handler() ? |
1546 | &rollback_except_vec_vi : &except_vec_vi; | 1548 | &rollback_except_vec_vi : &except_vec_vi; |
1547 | #ifdef CONFIG_MIPS_MT_SMTC | 1549 | #ifdef CONFIG_MIPS_MT_SMTC |
1548 | /* | 1550 | /* |
@@ -1656,7 +1658,6 @@ void __cpuinit per_cpu_trap_init(bool is_boot_cpu) | |||
1656 | unsigned int cpu = smp_processor_id(); | 1658 | unsigned int cpu = smp_processor_id(); |
1657 | unsigned int status_set = ST0_CU0; | 1659 | unsigned int status_set = ST0_CU0; |
1658 | unsigned int hwrena = cpu_hwrena_impl_bits; | 1660 | unsigned int hwrena = cpu_hwrena_impl_bits; |
1659 | unsigned long asid = 0; | ||
1660 | #ifdef CONFIG_MIPS_MT_SMTC | 1661 | #ifdef CONFIG_MIPS_MT_SMTC |
1661 | int secondaryTC = 0; | 1662 | int secondaryTC = 0; |
1662 | int bootTC = (cpu == 0); | 1663 | int bootTC = (cpu == 0); |
@@ -1740,9 +1741,8 @@ void __cpuinit per_cpu_trap_init(bool is_boot_cpu) | |||
1740 | } | 1741 | } |
1741 | #endif /* CONFIG_MIPS_MT_SMTC */ | 1742 | #endif /* CONFIG_MIPS_MT_SMTC */ |
1742 | 1743 | ||
1743 | asid = ASID_FIRST_VERSION; | 1744 | if (!cpu_data[cpu].asid_cache) |
1744 | cpu_data[cpu].asid_cache = asid; | 1745 | cpu_data[cpu].asid_cache = ASID_FIRST_VERSION; |
1745 | TLBMISS_HANDLER_SETUP(); | ||
1746 | 1746 | ||
1747 | atomic_inc(&init_mm.mm_count); | 1747 | atomic_inc(&init_mm.mm_count); |
1748 | current->active_mm = &init_mm; | 1748 | current->active_mm = &init_mm; |
@@ -1814,10 +1814,8 @@ void __init trap_init(void) | |||
1814 | extern char except_vec4; | 1814 | extern char except_vec4; |
1815 | extern char except_vec3_r4000; | 1815 | extern char except_vec3_r4000; |
1816 | unsigned long i; | 1816 | unsigned long i; |
1817 | int rollback; | ||
1818 | 1817 | ||
1819 | check_wait(); | 1818 | check_wait(); |
1820 | rollback = (cpu_wait == r4k_wait); | ||
1821 | 1819 | ||
1822 | #if defined(CONFIG_KGDB) | 1820 | #if defined(CONFIG_KGDB) |
1823 | if (kgdb_early_setup) | 1821 | if (kgdb_early_setup) |
@@ -1894,7 +1892,8 @@ void __init trap_init(void) | |||
1894 | if (board_be_init) | 1892 | if (board_be_init) |
1895 | board_be_init(); | 1893 | board_be_init(); |
1896 | 1894 | ||
1897 | set_except_vector(0, rollback ? rollback_handle_int : handle_int); | 1895 | set_except_vector(0, using_rollback_handler() ? rollback_handle_int |
1896 | : handle_int); | ||
1898 | set_except_vector(1, handle_tlbm); | 1897 | set_except_vector(1, handle_tlbm); |
1899 | set_except_vector(2, handle_tlbl); | 1898 | set_except_vector(2, handle_tlbl); |
1900 | set_except_vector(3, handle_tlbs); | 1899 | set_except_vector(3, handle_tlbs); |