diff options
| -rw-r--r-- | arch/mips/kernel/cpu-probe.c | 16 | ||||
| -rw-r--r-- | arch/mips/kernel/genex.S | 37 | ||||
| -rw-r--r-- | arch/mips/kernel/process.c | 2 | ||||
| -rw-r--r-- | arch/mips/kernel/traps.c | 22 | ||||
| -rw-r--r-- | arch/mips/kernel/vmlinux.lds.S | 1 | ||||
| -rw-r--r-- | arch/mips/lib/csum_partial.S | 21 |
6 files changed, 75 insertions, 24 deletions
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 335a6ae3d594..11c92dc53791 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
| @@ -45,18 +45,7 @@ static void r39xx_wait(void) | |||
| 45 | local_irq_enable(); | 45 | local_irq_enable(); |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | /* | 48 | extern void r4k_wait(void); |
| 49 | * There is a race when WAIT instruction executed with interrupt | ||
| 50 | * enabled. | ||
| 51 | * But it is implementation-dependent wheter the pipelie restarts when | ||
| 52 | * a non-enabled interrupt is requested. | ||
| 53 | */ | ||
| 54 | static void r4k_wait(void) | ||
| 55 | { | ||
| 56 | __asm__(" .set mips3 \n" | ||
| 57 | " wait \n" | ||
| 58 | " .set mips0 \n"); | ||
| 59 | } | ||
| 60 | 49 | ||
| 61 | /* | 50 | /* |
| 62 | * This variant is preferable as it allows testing need_resched and going to | 51 | * This variant is preferable as it allows testing need_resched and going to |
| @@ -128,7 +117,7 @@ static int __init wait_disable(char *s) | |||
| 128 | 117 | ||
| 129 | __setup("nowait", wait_disable); | 118 | __setup("nowait", wait_disable); |
| 130 | 119 | ||
| 131 | static inline void check_wait(void) | 120 | void __init check_wait(void) |
| 132 | { | 121 | { |
| 133 | struct cpuinfo_mips *c = ¤t_cpu_data; | 122 | struct cpuinfo_mips *c = ¤t_cpu_data; |
| 134 | 123 | ||
| @@ -242,7 +231,6 @@ static inline void check_errata(void) | |||
| 242 | 231 | ||
| 243 | void __init check_bugs32(void) | 232 | void __init check_bugs32(void) |
| 244 | { | 233 | { |
| 245 | check_wait(); | ||
| 246 | check_errata(); | 234 | check_errata(); |
| 247 | } | 235 | } |
| 248 | 236 | ||
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index c6ada98ee042..f886dd7f708e 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <asm/stackframe.h> | 20 | #include <asm/stackframe.h> |
| 21 | #include <asm/war.h> | 21 | #include <asm/war.h> |
| 22 | #include <asm/page.h> | 22 | #include <asm/page.h> |
| 23 | #include <asm/thread_info.h> | ||
| 23 | 24 | ||
| 24 | #define PANIC_PIC(msg) \ | 25 | #define PANIC_PIC(msg) \ |
| 25 | .set push; \ | 26 | .set push; \ |
| @@ -126,7 +127,42 @@ handle_vcei: | |||
| 126 | 127 | ||
| 127 | __FINIT | 128 | __FINIT |
| 128 | 129 | ||
| 130 | .align 5 /* 32 byte rollback region */ | ||
| 131 | LEAF(r4k_wait) | ||
| 132 | .set push | ||
| 133 | .set noreorder | ||
| 134 | /* start of rollback region */ | ||
| 135 | LONG_L t0, TI_FLAGS($28) | ||
| 136 | nop | ||
| 137 | andi t0, _TIF_NEED_RESCHED | ||
| 138 | bnez t0, 1f | ||
| 139 | nop | ||
| 140 | nop | ||
| 141 | nop | ||
| 142 | .set mips3 | ||
| 143 | wait | ||
| 144 | /* end of rollback region (the region size must be power of two) */ | ||
| 145 | .set pop | ||
| 146 | 1: | ||
| 147 | jr ra | ||
| 148 | END(r4k_wait) | ||
| 149 | |||
| 150 | .macro BUILD_ROLLBACK_PROLOGUE handler | ||
| 151 | FEXPORT(rollback_\handler) | ||
| 152 | .set push | ||
| 153 | .set noat | ||
| 154 | MFC0 k0, CP0_EPC | ||
| 155 | PTR_LA k1, r4k_wait | ||
| 156 | ori k0, 0x1f /* 32 byte rollback region */ | ||
| 157 | xori k0, 0x1f | ||
| 158 | bne k0, k1, 9f | ||
| 159 | MTC0 k0, CP0_EPC | ||
| 160 | 9: | ||
| 161 | .set pop | ||
| 162 | .endm | ||
| 163 | |||
| 129 | .align 5 | 164 | .align 5 |
| 165 | BUILD_ROLLBACK_PROLOGUE handle_int | ||
| 130 | NESTED(handle_int, PT_SIZE, sp) | 166 | NESTED(handle_int, PT_SIZE, sp) |
| 131 | #ifdef CONFIG_TRACE_IRQFLAGS | 167 | #ifdef CONFIG_TRACE_IRQFLAGS |
| 132 | /* | 168 | /* |
| @@ -201,6 +237,7 @@ NESTED(except_vec_ejtag_debug, 0, sp) | |||
| 201 | * This prototype is copied to ebase + n*IntCtl.VS and patched | 237 | * This prototype is copied to ebase + n*IntCtl.VS and patched |
| 202 | * to invoke the handler | 238 | * to invoke the handler |
| 203 | */ | 239 | */ |
| 240 | BUILD_ROLLBACK_PROLOGUE except_vec_vi | ||
| 204 | NESTED(except_vec_vi, 0, sp) | 241 | NESTED(except_vec_vi, 0, sp) |
| 205 | SAVE_SOME | 242 | SAVE_SOME |
| 206 | SAVE_AT | 243 | SAVE_AT |
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index b16facd9ea8e..ce7684335a41 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c | |||
| @@ -148,6 +148,8 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, | |||
| 148 | clear_tsk_thread_flag(p, TIF_USEDFPU); | 148 | clear_tsk_thread_flag(p, TIF_USEDFPU); |
| 149 | 149 | ||
| 150 | #ifdef CONFIG_MIPS_MT_FPAFF | 150 | #ifdef CONFIG_MIPS_MT_FPAFF |
| 151 | clear_tsk_thread_flag(p, TIF_FPUBOUND); | ||
| 152 | |||
| 151 | /* | 153 | /* |
| 152 | * FPU affinity support is cleaner if we track the | 154 | * FPU affinity support is cleaner if we track the |
| 153 | * user-visible CPU affinity from the very beginning. | 155 | * user-visible CPU affinity from the very beginning. |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 6bee29097a56..5fd0cd020af5 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
| @@ -46,6 +46,9 @@ | |||
| 46 | #include <asm/types.h> | 46 | #include <asm/types.h> |
| 47 | #include <asm/stacktrace.h> | 47 | #include <asm/stacktrace.h> |
| 48 | 48 | ||
| 49 | extern void check_wait(void); | ||
| 50 | extern asmlinkage void r4k_wait(void); | ||
| 51 | extern asmlinkage void rollback_handle_int(void); | ||
| 49 | extern asmlinkage void handle_int(void); | 52 | extern asmlinkage void handle_int(void); |
| 50 | extern asmlinkage void handle_tlbm(void); | 53 | extern asmlinkage void handle_tlbm(void); |
| 51 | extern asmlinkage void handle_tlbl(void); | 54 | extern asmlinkage void handle_tlbl(void); |
| @@ -1251,6 +1254,9 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) | |||
| 1251 | 1254 | ||
| 1252 | extern char except_vec_vi, except_vec_vi_lui; | 1255 | extern char except_vec_vi, except_vec_vi_lui; |
| 1253 | extern char except_vec_vi_ori, except_vec_vi_end; | 1256 | extern char except_vec_vi_ori, except_vec_vi_end; |
| 1257 | extern char rollback_except_vec_vi; | ||
| 1258 | char *vec_start = (cpu_wait == r4k_wait) ? | ||
| 1259 | &rollback_except_vec_vi : &except_vec_vi; | ||
| 1254 | #ifdef CONFIG_MIPS_MT_SMTC | 1260 | #ifdef CONFIG_MIPS_MT_SMTC |
| 1255 | /* | 1261 | /* |
| 1256 | * We need to provide the SMTC vectored interrupt handler | 1262 | * We need to provide the SMTC vectored interrupt handler |
| @@ -1258,11 +1264,11 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) | |||
| 1258 | * Status.IM bit to be masked before going there. | 1264 | * Status.IM bit to be masked before going there. |
| 1259 | */ | 1265 | */ |
| 1260 | extern char except_vec_vi_mori; | 1266 | extern char except_vec_vi_mori; |
| 1261 | const int mori_offset = &except_vec_vi_mori - &except_vec_vi; | 1267 | const int mori_offset = &except_vec_vi_mori - vec_start; |
| 1262 | #endif /* CONFIG_MIPS_MT_SMTC */ | 1268 | #endif /* CONFIG_MIPS_MT_SMTC */ |
| 1263 | const int handler_len = &except_vec_vi_end - &except_vec_vi; | 1269 | const int handler_len = &except_vec_vi_end - vec_start; |
| 1264 | const int lui_offset = &except_vec_vi_lui - &except_vec_vi; | 1270 | const int lui_offset = &except_vec_vi_lui - vec_start; |
| 1265 | const int ori_offset = &except_vec_vi_ori - &except_vec_vi; | 1271 | const int ori_offset = &except_vec_vi_ori - vec_start; |
| 1266 | 1272 | ||
| 1267 | if (handler_len > VECTORSPACING) { | 1273 | if (handler_len > VECTORSPACING) { |
| 1268 | /* | 1274 | /* |
| @@ -1272,7 +1278,7 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) | |||
| 1272 | panic("VECTORSPACING too small"); | 1278 | panic("VECTORSPACING too small"); |
| 1273 | } | 1279 | } |
| 1274 | 1280 | ||
| 1275 | memcpy(b, &except_vec_vi, handler_len); | 1281 | memcpy(b, vec_start, handler_len); |
| 1276 | #ifdef CONFIG_MIPS_MT_SMTC | 1282 | #ifdef CONFIG_MIPS_MT_SMTC |
| 1277 | BUG_ON(n > 7); /* Vector index %d exceeds SMTC maximum. */ | 1283 | BUG_ON(n > 7); /* Vector index %d exceeds SMTC maximum. */ |
| 1278 | 1284 | ||
| @@ -1554,6 +1560,10 @@ void __init trap_init(void) | |||
| 1554 | extern char except_vec3_generic, except_vec3_r4000; | 1560 | extern char except_vec3_generic, except_vec3_r4000; |
| 1555 | extern char except_vec4; | 1561 | extern char except_vec4; |
| 1556 | unsigned long i; | 1562 | unsigned long i; |
| 1563 | int rollback; | ||
| 1564 | |||
| 1565 | check_wait(); | ||
| 1566 | rollback = (cpu_wait == r4k_wait); | ||
| 1557 | 1567 | ||
| 1558 | #if defined(CONFIG_KGDB) | 1568 | #if defined(CONFIG_KGDB) |
| 1559 | if (kgdb_early_setup) | 1569 | if (kgdb_early_setup) |
| @@ -1618,7 +1628,7 @@ void __init trap_init(void) | |||
| 1618 | if (board_be_init) | 1628 | if (board_be_init) |
| 1619 | board_be_init(); | 1629 | board_be_init(); |
| 1620 | 1630 | ||
| 1621 | set_except_vector(0, handle_int); | 1631 | set_except_vector(0, rollback ? rollback_handle_int : handle_int); |
| 1622 | set_except_vector(1, handle_tlbm); | 1632 | set_except_vector(1, handle_tlbm); |
| 1623 | set_except_vector(2, handle_tlbl); | 1633 | set_except_vector(2, handle_tlbl); |
| 1624 | set_except_vector(3, handle_tlbs); | 1634 | set_except_vector(3, handle_tlbs); |
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index b5470ceb418b..afb119f35682 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S | |||
| @@ -36,6 +36,7 @@ SECTIONS | |||
| 36 | SCHED_TEXT | 36 | SCHED_TEXT |
| 37 | LOCK_TEXT | 37 | LOCK_TEXT |
| 38 | KPROBES_TEXT | 38 | KPROBES_TEXT |
| 39 | *(.text.*) | ||
| 39 | *(.fixup) | 40 | *(.fixup) |
| 40 | *(.gnu.warning) | 41 | *(.gnu.warning) |
| 41 | } :text = 0 | 42 | } :text = 0 |
diff --git a/arch/mips/lib/csum_partial.S b/arch/mips/lib/csum_partial.S index 8d7784122c14..edac9892c51a 100644 --- a/arch/mips/lib/csum_partial.S +++ b/arch/mips/lib/csum_partial.S | |||
| @@ -39,12 +39,14 @@ | |||
| 39 | #ifdef USE_DOUBLE | 39 | #ifdef USE_DOUBLE |
| 40 | 40 | ||
| 41 | #define LOAD ld | 41 | #define LOAD ld |
| 42 | #define LOAD32 lwu | ||
| 42 | #define ADD daddu | 43 | #define ADD daddu |
| 43 | #define NBYTES 8 | 44 | #define NBYTES 8 |
| 44 | 45 | ||
| 45 | #else | 46 | #else |
| 46 | 47 | ||
| 47 | #define LOAD lw | 48 | #define LOAD lw |
| 49 | #define LOAD32 lw | ||
| 48 | #define ADD addu | 50 | #define ADD addu |
| 49 | #define NBYTES 4 | 51 | #define NBYTES 4 |
| 50 | 52 | ||
| @@ -60,6 +62,14 @@ | |||
| 60 | ADD sum, v1; \ | 62 | ADD sum, v1; \ |
| 61 | .set pop | 63 | .set pop |
| 62 | 64 | ||
| 65 | #define ADDC32(sum,reg) \ | ||
| 66 | .set push; \ | ||
| 67 | .set noat; \ | ||
| 68 | addu sum, reg; \ | ||
| 69 | sltu v1, sum, reg; \ | ||
| 70 | addu sum, v1; \ | ||
| 71 | .set pop | ||
| 72 | |||
| 63 | #define CSUM_BIGCHUNK1(src, offset, sum, _t0, _t1, _t2, _t3) \ | 73 | #define CSUM_BIGCHUNK1(src, offset, sum, _t0, _t1, _t2, _t3) \ |
| 64 | LOAD _t0, (offset + UNIT(0))(src); \ | 74 | LOAD _t0, (offset + UNIT(0))(src); \ |
| 65 | LOAD _t1, (offset + UNIT(1))(src); \ | 75 | LOAD _t1, (offset + UNIT(1))(src); \ |
| @@ -132,7 +142,7 @@ LEAF(csum_partial) | |||
| 132 | beqz t8, .Lqword_align | 142 | beqz t8, .Lqword_align |
| 133 | andi t8, src, 0x8 | 143 | andi t8, src, 0x8 |
| 134 | 144 | ||
| 135 | lw t0, 0x00(src) | 145 | LOAD32 t0, 0x00(src) |
| 136 | LONG_SUBU a1, a1, 0x4 | 146 | LONG_SUBU a1, a1, 0x4 |
| 137 | ADDC(sum, t0) | 147 | ADDC(sum, t0) |
| 138 | PTR_ADDU src, src, 0x4 | 148 | PTR_ADDU src, src, 0x4 |
| @@ -211,7 +221,7 @@ LEAF(csum_partial) | |||
| 211 | LONG_SRL t8, t8, 0x2 | 221 | LONG_SRL t8, t8, 0x2 |
| 212 | 222 | ||
| 213 | .Lend_words: | 223 | .Lend_words: |
| 214 | lw t0, (src) | 224 | LOAD32 t0, (src) |
| 215 | LONG_SUBU t8, t8, 0x1 | 225 | LONG_SUBU t8, t8, 0x1 |
| 216 | ADDC(sum, t0) | 226 | ADDC(sum, t0) |
| 217 | .set reorder /* DADDI_WAR */ | 227 | .set reorder /* DADDI_WAR */ |
| @@ -230,6 +240,9 @@ LEAF(csum_partial) | |||
| 230 | /* Still a full word to go */ | 240 | /* Still a full word to go */ |
| 231 | ulw t1, (src) | 241 | ulw t1, (src) |
| 232 | PTR_ADDIU src, 4 | 242 | PTR_ADDIU src, 4 |
| 243 | #ifdef USE_DOUBLE | ||
| 244 | dsll t1, t1, 32 /* clear lower 32bit */ | ||
| 245 | #endif | ||
| 233 | ADDC(sum, t1) | 246 | ADDC(sum, t1) |
| 234 | 247 | ||
| 235 | 1: move t1, zero | 248 | 1: move t1, zero |
| @@ -280,7 +293,7 @@ LEAF(csum_partial) | |||
| 280 | 1: | 293 | 1: |
| 281 | .set reorder | 294 | .set reorder |
| 282 | /* Add the passed partial csum. */ | 295 | /* Add the passed partial csum. */ |
| 283 | ADDC(sum, a2) | 296 | ADDC32(sum, a2) |
| 284 | jr ra | 297 | jr ra |
| 285 | .set noreorder | 298 | .set noreorder |
| 286 | END(csum_partial) | 299 | END(csum_partial) |
| @@ -681,7 +694,7 @@ EXC( sb t0, NBYTES-2(dst), .Ls_exc) | |||
| 681 | .set pop | 694 | .set pop |
| 682 | 1: | 695 | 1: |
| 683 | .set reorder | 696 | .set reorder |
| 684 | ADDC(sum, psum) | 697 | ADDC32(sum, psum) |
| 685 | jr ra | 698 | jr ra |
| 686 | .set noreorder | 699 | .set noreorder |
| 687 | 700 | ||
