diff options
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/Makefile | 1 | ||||
-rw-r--r-- | arch/mips/kernel/process.c | 158 | ||||
-rw-r--r-- | arch/mips/kernel/scall32-o32.S | 2 | ||||
-rw-r--r-- | arch/mips/kernel/signal-common.h | 2 | ||||
-rw-r--r-- | arch/mips/kernel/signal32.c | 2 | ||||
-rw-r--r-- | arch/mips/kernel/signal_n32.c | 2 | ||||
-rw-r--r-- | arch/mips/kernel/smp_mt.c | 34 | ||||
-rw-r--r-- | arch/mips/mm/c-r4k.c | 104 | ||||
-rw-r--r-- | arch/mips/mm/c-tx39.c | 70 |
9 files changed, 109 insertions, 266 deletions
diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 6a57407df1bc..38c0f3360d51 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile | |||
@@ -94,7 +94,6 @@ endif | |||
94 | # machines may also. Since BFD is incredibly buggy with respect to | 94 | # machines may also. Since BFD is incredibly buggy with respect to |
95 | # crossformat linking we rely on the elf2ecoff tool for format conversion. | 95 | # crossformat linking we rely on the elf2ecoff tool for format conversion. |
96 | # | 96 | # |
97 | cflags-y += -I $(TOPDIR)/include/asm/gcc | ||
98 | cflags-y += -G 0 -mno-abicalls -fno-pic -pipe | 97 | cflags-y += -G 0 -mno-abicalls -fno-pic -pipe |
99 | LDFLAGS_vmlinux += -G 0 -static -n -nostdlib | 98 | LDFLAGS_vmlinux += -G 0 -static -n -nostdlib |
100 | MODFLAGS += -mlong-calls | 99 | MODFLAGS += -mlong-calls |
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 5232fc752935..092679c2dca9 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/a.out.h> | 25 | #include <linux/a.out.h> |
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/completion.h> | 27 | #include <linux/completion.h> |
28 | #include <linux/kallsyms.h> | ||
28 | 29 | ||
29 | #include <asm/abi.h> | 30 | #include <asm/abi.h> |
30 | #include <asm/bootinfo.h> | 31 | #include <asm/bootinfo.h> |
@@ -272,46 +273,19 @@ long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | |||
272 | 273 | ||
273 | static struct mips_frame_info { | 274 | static struct mips_frame_info { |
274 | void *func; | 275 | void *func; |
275 | int omit_fp; /* compiled without fno-omit-frame-pointer */ | 276 | unsigned long func_size; |
276 | int frame_offset; | 277 | int frame_size; |
277 | int pc_offset; | 278 | int pc_offset; |
278 | } schedule_frame, mfinfo[] = { | 279 | } *schedule_frame, mfinfo[64]; |
279 | { schedule, 0 }, /* must be first */ | 280 | static int mfinfo_num; |
280 | /* arch/mips/kernel/semaphore.c */ | ||
281 | { __down, 1 }, | ||
282 | { __down_interruptible, 1 }, | ||
283 | /* kernel/sched.c */ | ||
284 | #ifdef CONFIG_PREEMPT | ||
285 | { preempt_schedule, 0 }, | ||
286 | #endif | ||
287 | { wait_for_completion, 0 }, | ||
288 | { interruptible_sleep_on, 0 }, | ||
289 | { interruptible_sleep_on_timeout, 0 }, | ||
290 | { sleep_on, 0 }, | ||
291 | { sleep_on_timeout, 0 }, | ||
292 | { yield, 0 }, | ||
293 | { io_schedule, 0 }, | ||
294 | { io_schedule_timeout, 0 }, | ||
295 | #if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT) | ||
296 | { __preempt_spin_lock, 0 }, | ||
297 | { __preempt_write_lock, 0 }, | ||
298 | #endif | ||
299 | /* kernel/timer.c */ | ||
300 | { schedule_timeout, 1 }, | ||
301 | /* { nanosleep_restart, 1 }, */ | ||
302 | /* lib/rwsem-spinlock.c */ | ||
303 | { __down_read, 1 }, | ||
304 | { __down_write, 1 }, | ||
305 | }; | ||
306 | 281 | ||
307 | static int mips_frame_info_initialized; | ||
308 | static int __init get_frame_info(struct mips_frame_info *info) | 282 | static int __init get_frame_info(struct mips_frame_info *info) |
309 | { | 283 | { |
310 | int i; | 284 | int i; |
311 | void *func = info->func; | 285 | void *func = info->func; |
312 | union mips_instruction *ip = (union mips_instruction *)func; | 286 | union mips_instruction *ip = (union mips_instruction *)func; |
313 | info->pc_offset = -1; | 287 | info->pc_offset = -1; |
314 | info->frame_offset = info->omit_fp ? 0 : -1; | 288 | info->frame_size = 0; |
315 | for (i = 0; i < 128; i++, ip++) { | 289 | for (i = 0; i < 128; i++, ip++) { |
316 | /* if jal, jalr, jr, stop. */ | 290 | /* if jal, jalr, jr, stop. */ |
317 | if (ip->j_format.opcode == jal_op || | 291 | if (ip->j_format.opcode == jal_op || |
@@ -320,6 +294,23 @@ static int __init get_frame_info(struct mips_frame_info *info) | |||
320 | ip->r_format.func == jr_op))) | 294 | ip->r_format.func == jr_op))) |
321 | break; | 295 | break; |
322 | 296 | ||
297 | if (info->func_size && i >= info->func_size / 4) | ||
298 | break; | ||
299 | if ( | ||
300 | #ifdef CONFIG_32BIT | ||
301 | ip->i_format.opcode == addiu_op && | ||
302 | #endif | ||
303 | #ifdef CONFIG_64BIT | ||
304 | ip->i_format.opcode == daddiu_op && | ||
305 | #endif | ||
306 | ip->i_format.rs == 29 && | ||
307 | ip->i_format.rt == 29) { | ||
308 | /* addiu/daddiu sp,sp,-imm */ | ||
309 | if (info->frame_size) | ||
310 | continue; | ||
311 | info->frame_size = - ip->i_format.simmediate; | ||
312 | } | ||
313 | |||
323 | if ( | 314 | if ( |
324 | #ifdef CONFIG_32BIT | 315 | #ifdef CONFIG_32BIT |
325 | ip->i_format.opcode == sw_op && | 316 | ip->i_format.opcode == sw_op && |
@@ -327,31 +318,20 @@ static int __init get_frame_info(struct mips_frame_info *info) | |||
327 | #ifdef CONFIG_64BIT | 318 | #ifdef CONFIG_64BIT |
328 | ip->i_format.opcode == sd_op && | 319 | ip->i_format.opcode == sd_op && |
329 | #endif | 320 | #endif |
330 | ip->i_format.rs == 29) | 321 | ip->i_format.rs == 29 && |
331 | { | 322 | ip->i_format.rt == 31) { |
332 | /* sw / sd $ra, offset($sp) */ | 323 | /* sw / sd $ra, offset($sp) */ |
333 | if (ip->i_format.rt == 31) { | 324 | if (info->pc_offset != -1) |
334 | if (info->pc_offset != -1) | 325 | continue; |
335 | continue; | 326 | info->pc_offset = |
336 | info->pc_offset = | 327 | ip->i_format.simmediate / sizeof(long); |
337 | ip->i_format.simmediate / sizeof(long); | ||
338 | } | ||
339 | /* sw / sd $s8, offset($sp) */ | ||
340 | if (ip->i_format.rt == 30) { | ||
341 | //#if 0 /* gcc 3.4 does aggressive optimization... */ | ||
342 | if (info->frame_offset != -1) | ||
343 | continue; | ||
344 | //#endif | ||
345 | info->frame_offset = | ||
346 | ip->i_format.simmediate / sizeof(long); | ||
347 | } | ||
348 | } | 328 | } |
349 | } | 329 | } |
350 | if (info->pc_offset == -1 || info->frame_offset == -1) { | 330 | if (info->pc_offset == -1 || info->frame_size == 0) { |
351 | printk("Can't analyze prologue code at %p\n", func); | 331 | if (func == schedule) |
332 | printk("Can't analyze prologue code at %p\n", func); | ||
352 | info->pc_offset = -1; | 333 | info->pc_offset = -1; |
353 | info->frame_offset = -1; | 334 | info->frame_size = 0; |
354 | return -1; | ||
355 | } | 335 | } |
356 | 336 | ||
357 | return 0; | 337 | return 0; |
@@ -359,25 +339,36 @@ static int __init get_frame_info(struct mips_frame_info *info) | |||
359 | 339 | ||
360 | static int __init frame_info_init(void) | 340 | static int __init frame_info_init(void) |
361 | { | 341 | { |
362 | int i, found; | 342 | int i; |
363 | for (i = 0; i < ARRAY_SIZE(mfinfo); i++) | 343 | #ifdef CONFIG_KALLSYMS |
364 | if (get_frame_info(&mfinfo[i])) | 344 | char *modname; |
365 | return -1; | 345 | char namebuf[KSYM_NAME_LEN + 1]; |
366 | schedule_frame = mfinfo[0]; | 346 | unsigned long start, size, ofs; |
367 | /* bubble sort */ | 347 | extern char __sched_text_start[], __sched_text_end[]; |
368 | do { | 348 | extern char __lock_text_start[], __lock_text_end[]; |
369 | struct mips_frame_info tmp; | 349 | |
370 | found = 0; | 350 | start = (unsigned long)__sched_text_start; |
371 | for (i = 1; i < ARRAY_SIZE(mfinfo); i++) { | 351 | for (i = 0; i < ARRAY_SIZE(mfinfo); i++) { |
372 | if (mfinfo[i-1].func > mfinfo[i].func) { | 352 | if (start == (unsigned long)schedule) |
373 | tmp = mfinfo[i]; | 353 | schedule_frame = &mfinfo[i]; |
374 | mfinfo[i] = mfinfo[i-1]; | 354 | if (!kallsyms_lookup(start, &size, &ofs, &modname, namebuf)) |
375 | mfinfo[i-1] = tmp; | 355 | break; |
376 | found = 1; | 356 | mfinfo[i].func = (void *)(start + ofs); |
377 | } | 357 | mfinfo[i].func_size = size; |
378 | } | 358 | start += size - ofs; |
379 | } while (found); | 359 | if (start >= (unsigned long)__lock_text_end) |
380 | mips_frame_info_initialized = 1; | 360 | break; |
361 | if (start == (unsigned long)__sched_text_end) | ||
362 | start = (unsigned long)__lock_text_start; | ||
363 | } | ||
364 | #else | ||
365 | mfinfo[0].func = schedule; | ||
366 | schedule_frame = &mfinfo[0]; | ||
367 | #endif | ||
368 | for (i = 0; i < ARRAY_SIZE(mfinfo) && mfinfo[i].func; i++) | ||
369 | get_frame_info(&mfinfo[i]); | ||
370 | |||
371 | mfinfo_num = i; | ||
381 | return 0; | 372 | return 0; |
382 | } | 373 | } |
383 | 374 | ||
@@ -394,47 +385,52 @@ unsigned long thread_saved_pc(struct task_struct *tsk) | |||
394 | if (t->reg31 == (unsigned long) ret_from_fork) | 385 | if (t->reg31 == (unsigned long) ret_from_fork) |
395 | return t->reg31; | 386 | return t->reg31; |
396 | 387 | ||
397 | if (schedule_frame.pc_offset < 0) | 388 | if (!schedule_frame || schedule_frame->pc_offset < 0) |
398 | return 0; | 389 | return 0; |
399 | return ((unsigned long *)t->reg29)[schedule_frame.pc_offset]; | 390 | return ((unsigned long *)t->reg29)[schedule_frame->pc_offset]; |
400 | } | 391 | } |
401 | 392 | ||
402 | /* get_wchan - a maintenance nightmare^W^Wpain in the ass ... */ | 393 | /* get_wchan - a maintenance nightmare^W^Wpain in the ass ... */ |
403 | unsigned long get_wchan(struct task_struct *p) | 394 | unsigned long get_wchan(struct task_struct *p) |
404 | { | 395 | { |
405 | unsigned long stack_page; | 396 | unsigned long stack_page; |
406 | unsigned long frame, pc; | 397 | unsigned long pc; |
398 | #ifdef CONFIG_KALLSYMS | ||
399 | unsigned long frame; | ||
400 | #endif | ||
407 | 401 | ||
408 | if (!p || p == current || p->state == TASK_RUNNING) | 402 | if (!p || p == current || p->state == TASK_RUNNING) |
409 | return 0; | 403 | return 0; |
410 | 404 | ||
411 | stack_page = (unsigned long)task_stack_page(p); | 405 | stack_page = (unsigned long)task_stack_page(p); |
412 | if (!stack_page || !mips_frame_info_initialized) | 406 | if (!stack_page || !mfinfo_num) |
413 | return 0; | 407 | return 0; |
414 | 408 | ||
415 | pc = thread_saved_pc(p); | 409 | pc = thread_saved_pc(p); |
410 | #ifdef CONFIG_KALLSYMS | ||
416 | if (!in_sched_functions(pc)) | 411 | if (!in_sched_functions(pc)) |
417 | return pc; | 412 | return pc; |
418 | 413 | ||
419 | frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset]; | 414 | frame = p->thread.reg29 + schedule_frame->frame_size; |
420 | do { | 415 | do { |
421 | int i; | 416 | int i; |
422 | 417 | ||
423 | if (frame < stack_page || frame > stack_page + THREAD_SIZE - 32) | 418 | if (frame < stack_page || frame > stack_page + THREAD_SIZE - 32) |
424 | return 0; | 419 | return 0; |
425 | 420 | ||
426 | for (i = ARRAY_SIZE(mfinfo) - 1; i >= 0; i--) { | 421 | for (i = mfinfo_num - 1; i >= 0; i--) { |
427 | if (pc >= (unsigned long) mfinfo[i].func) | 422 | if (pc >= (unsigned long) mfinfo[i].func) |
428 | break; | 423 | break; |
429 | } | 424 | } |
430 | if (i < 0) | 425 | if (i < 0) |
431 | break; | 426 | break; |
432 | 427 | ||
433 | if (mfinfo[i].omit_fp) | ||
434 | break; | ||
435 | pc = ((unsigned long *)frame)[mfinfo[i].pc_offset]; | 428 | pc = ((unsigned long *)frame)[mfinfo[i].pc_offset]; |
436 | frame = ((unsigned long *)frame)[mfinfo[i].frame_offset]; | 429 | if (!mfinfo[i].frame_size) |
430 | break; | ||
431 | frame += mfinfo[i].frame_size; | ||
437 | } while (in_sched_functions(pc)); | 432 | } while (in_sched_functions(pc)); |
433 | #endif | ||
438 | 434 | ||
439 | return pc; | 435 | return pc; |
440 | } | 436 | } |
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index d7c4a38ed5ae..d83e033dbc87 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S | |||
@@ -623,7 +623,7 @@ einval: li v0, -EINVAL | |||
623 | sys sys_mknodat 4 /* 4290 */ | 623 | sys sys_mknodat 4 /* 4290 */ |
624 | sys sys_fchownat 5 | 624 | sys sys_fchownat 5 |
625 | sys sys_futimesat 3 | 625 | sys sys_futimesat 3 |
626 | sys sys_newfstatat 4 | 626 | sys sys_fstatat64 4 |
627 | sys sys_unlinkat 3 | 627 | sys sys_unlinkat 3 |
628 | sys sys_renameat 4 /* 4295 */ | 628 | sys sys_renameat 4 /* 4295 */ |
629 | sys sys_linkat 4 | 629 | sys sys_linkat 4 |
diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h index 0fbc492d24b4..36bfc2588aa3 100644 --- a/arch/mips/kernel/signal-common.h +++ b/arch/mips/kernel/signal-common.h | |||
@@ -176,7 +176,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) | |||
176 | if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0)) | 176 | if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0)) |
177 | sp = current->sas_ss_sp + current->sas_ss_size; | 177 | sp = current->sas_ss_sp + current->sas_ss_size; |
178 | 178 | ||
179 | return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? 32 : ALMASK)); | 179 | return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK)); |
180 | } | 180 | } |
181 | 181 | ||
182 | static inline int install_sigtramp(unsigned int __user *tramp, | 182 | static inline int install_sigtramp(unsigned int __user *tramp, |
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c index da3271e1fdac..8a8b8dd90417 100644 --- a/arch/mips/kernel/signal32.c +++ b/arch/mips/kernel/signal32.c | |||
@@ -537,7 +537,7 @@ _sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) | |||
537 | /* The ucontext contains a stack32_t, so we must convert! */ | 537 | /* The ucontext contains a stack32_t, so we must convert! */ |
538 | if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp)) | 538 | if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp)) |
539 | goto badframe; | 539 | goto badframe; |
540 | st.ss_size = (long) sp; | 540 | st.ss_sp = (void *)(long) sp; |
541 | if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size)) | 541 | if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size)) |
542 | goto badframe; | 542 | goto badframe; |
543 | if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags)) | 543 | if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags)) |
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c index 384fc4a639a4..5a3776096f07 100644 --- a/arch/mips/kernel/signal_n32.c +++ b/arch/mips/kernel/signal_n32.c | |||
@@ -108,7 +108,7 @@ _sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) | |||
108 | /* The ucontext contains a stack32_t, so we must convert! */ | 108 | /* The ucontext contains a stack32_t, so we must convert! */ |
109 | if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp)) | 109 | if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp)) |
110 | goto badframe; | 110 | goto badframe; |
111 | st.ss_size = (long) sp; | 111 | st.ss_sp = (void *)(long) sp; |
112 | if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size)) | 112 | if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size)) |
113 | goto badframe; | 113 | goto badframe; |
114 | if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags)) | 114 | if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags)) |
diff --git a/arch/mips/kernel/smp_mt.c b/arch/mips/kernel/smp_mt.c index 794a1c3de2a4..c930364830d0 100644 --- a/arch/mips/kernel/smp_mt.c +++ b/arch/mips/kernel/smp_mt.c | |||
@@ -68,6 +68,8 @@ void __init sanitize_tlb_entries(void) | |||
68 | 68 | ||
69 | set_c0_mvpcontrol(MVPCONTROL_VPC); | 69 | set_c0_mvpcontrol(MVPCONTROL_VPC); |
70 | 70 | ||
71 | back_to_back_c0_hazard(); | ||
72 | |||
71 | /* Disable TLB sharing */ | 73 | /* Disable TLB sharing */ |
72 | clear_c0_mvpcontrol(MVPCONTROL_STLB); | 74 | clear_c0_mvpcontrol(MVPCONTROL_STLB); |
73 | 75 | ||
@@ -102,35 +104,6 @@ void __init sanitize_tlb_entries(void) | |||
102 | clear_c0_mvpcontrol(MVPCONTROL_VPC); | 104 | clear_c0_mvpcontrol(MVPCONTROL_VPC); |
103 | } | 105 | } |
104 | 106 | ||
105 | #if 0 | ||
106 | /* | ||
107 | * Use c0_MVPConf0 to find out how many CPUs are available, setting up | ||
108 | * phys_cpu_present_map and the logical/physical mappings. | ||
109 | */ | ||
110 | void __init prom_build_cpu_map(void) | ||
111 | { | ||
112 | int i, num, ncpus; | ||
113 | |||
114 | cpus_clear(phys_cpu_present_map); | ||
115 | |||
116 | /* assume we boot on cpu 0.... */ | ||
117 | cpu_set(0, phys_cpu_present_map); | ||
118 | __cpu_number_map[0] = 0; | ||
119 | __cpu_logical_map[0] = 0; | ||
120 | |||
121 | if (cpu_has_mipsmt) { | ||
122 | ncpus = ((read_c0_mvpconf0() & (MVPCONF0_PVPE)) >> MVPCONF0_PVPE_SHIFT) + 1; | ||
123 | for (i=1, num=0; i< NR_CPUS && i<ncpus; i++) { | ||
124 | cpu_set(i, phys_cpu_present_map); | ||
125 | __cpu_number_map[i] = ++num; | ||
126 | __cpu_logical_map[num] = i; | ||
127 | } | ||
128 | |||
129 | printk(KERN_INFO "%i available secondary CPU(s)\n", num); | ||
130 | } | ||
131 | } | ||
132 | #endif | ||
133 | |||
134 | static void ipi_resched_dispatch (struct pt_regs *regs) | 107 | static void ipi_resched_dispatch (struct pt_regs *regs) |
135 | { | 108 | { |
136 | do_IRQ(MIPS_CPU_IPI_RESCHED_IRQ, regs); | 109 | do_IRQ(MIPS_CPU_IPI_RESCHED_IRQ, regs); |
@@ -222,6 +195,9 @@ void prom_prepare_cpus(unsigned int max_cpus) | |||
222 | 195 | ||
223 | /* set config to be the same as vpe0, particularly kseg0 coherency alg */ | 196 | /* set config to be the same as vpe0, particularly kseg0 coherency alg */ |
224 | write_vpe_c0_config( read_c0_config()); | 197 | write_vpe_c0_config( read_c0_config()); |
198 | |||
199 | /* Propagate Config7 */ | ||
200 | write_vpe_c0_config7(read_c0_config7()); | ||
225 | } | 201 | } |
226 | 202 | ||
227 | } | 203 | } |
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index e51c38cef88e..1b71d91e8268 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c | |||
@@ -471,61 +471,29 @@ struct flush_icache_range_args { | |||
471 | static inline void local_r4k_flush_icache_range(void *args) | 471 | static inline void local_r4k_flush_icache_range(void *args) |
472 | { | 472 | { |
473 | struct flush_icache_range_args *fir_args = args; | 473 | struct flush_icache_range_args *fir_args = args; |
474 | unsigned long dc_lsize = cpu_dcache_line_size(); | ||
475 | unsigned long ic_lsize = cpu_icache_line_size(); | ||
476 | unsigned long sc_lsize = cpu_scache_line_size(); | ||
477 | unsigned long start = fir_args->start; | 474 | unsigned long start = fir_args->start; |
478 | unsigned long end = fir_args->end; | 475 | unsigned long end = fir_args->end; |
479 | unsigned long addr, aend; | ||
480 | 476 | ||
481 | if (!cpu_has_ic_fills_f_dc) { | 477 | if (!cpu_has_ic_fills_f_dc) { |
482 | if (end - start > dcache_size) { | 478 | if (end - start > dcache_size) { |
483 | r4k_blast_dcache(); | 479 | r4k_blast_dcache(); |
484 | } else { | 480 | } else { |
485 | R4600_HIT_CACHEOP_WAR_IMPL; | 481 | R4600_HIT_CACHEOP_WAR_IMPL; |
486 | addr = start & ~(dc_lsize - 1); | 482 | protected_blast_dcache_range(start, end); |
487 | aend = (end - 1) & ~(dc_lsize - 1); | ||
488 | |||
489 | while (1) { | ||
490 | /* Hit_Writeback_Inv_D */ | ||
491 | protected_writeback_dcache_line(addr); | ||
492 | if (addr == aend) | ||
493 | break; | ||
494 | addr += dc_lsize; | ||
495 | } | ||
496 | } | 483 | } |
497 | 484 | ||
498 | if (!cpu_icache_snoops_remote_store) { | 485 | if (!cpu_icache_snoops_remote_store) { |
499 | if (end - start > scache_size) { | 486 | if (end - start > scache_size) |
500 | r4k_blast_scache(); | 487 | r4k_blast_scache(); |
501 | } else { | 488 | else |
502 | addr = start & ~(sc_lsize - 1); | 489 | protected_blast_scache_range(start, end); |
503 | aend = (end - 1) & ~(sc_lsize - 1); | ||
504 | |||
505 | while (1) { | ||
506 | /* Hit_Writeback_Inv_SD */ | ||
507 | protected_writeback_scache_line(addr); | ||
508 | if (addr == aend) | ||
509 | break; | ||
510 | addr += sc_lsize; | ||
511 | } | ||
512 | } | ||
513 | } | 490 | } |
514 | } | 491 | } |
515 | 492 | ||
516 | if (end - start > icache_size) | 493 | if (end - start > icache_size) |
517 | r4k_blast_icache(); | 494 | r4k_blast_icache(); |
518 | else { | 495 | else |
519 | addr = start & ~(ic_lsize - 1); | 496 | protected_blast_icache_range(start, end); |
520 | aend = (end - 1) & ~(ic_lsize - 1); | ||
521 | while (1) { | ||
522 | /* Hit_Invalidate_I */ | ||
523 | protected_flush_icache_line(addr); | ||
524 | if (addr == aend) | ||
525 | break; | ||
526 | addr += ic_lsize; | ||
527 | } | ||
528 | } | ||
529 | } | 497 | } |
530 | 498 | ||
531 | static void r4k_flush_icache_range(unsigned long start, unsigned long end) | 499 | static void r4k_flush_icache_range(unsigned long start, unsigned long end) |
@@ -619,27 +587,14 @@ static void r4k_flush_icache_page(struct vm_area_struct *vma, | |||
619 | 587 | ||
620 | static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) | 588 | static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) |
621 | { | 589 | { |
622 | unsigned long end, a; | ||
623 | |||
624 | /* Catch bad driver code */ | 590 | /* Catch bad driver code */ |
625 | BUG_ON(size == 0); | 591 | BUG_ON(size == 0); |
626 | 592 | ||
627 | if (cpu_has_subset_pcaches) { | 593 | if (cpu_has_subset_pcaches) { |
628 | unsigned long sc_lsize = cpu_scache_line_size(); | 594 | if (size >= scache_size) |
629 | |||
630 | if (size >= scache_size) { | ||
631 | r4k_blast_scache(); | 595 | r4k_blast_scache(); |
632 | return; | 596 | else |
633 | } | 597 | blast_scache_range(addr, addr + size); |
634 | |||
635 | a = addr & ~(sc_lsize - 1); | ||
636 | end = (addr + size - 1) & ~(sc_lsize - 1); | ||
637 | while (1) { | ||
638 | flush_scache_line(a); /* Hit_Writeback_Inv_SD */ | ||
639 | if (a == end) | ||
640 | break; | ||
641 | a += sc_lsize; | ||
642 | } | ||
643 | return; | 598 | return; |
644 | } | 599 | } |
645 | 600 | ||
@@ -651,17 +606,8 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) | |||
651 | if (size >= dcache_size) { | 606 | if (size >= dcache_size) { |
652 | r4k_blast_dcache(); | 607 | r4k_blast_dcache(); |
653 | } else { | 608 | } else { |
654 | unsigned long dc_lsize = cpu_dcache_line_size(); | ||
655 | |||
656 | R4600_HIT_CACHEOP_WAR_IMPL; | 609 | R4600_HIT_CACHEOP_WAR_IMPL; |
657 | a = addr & ~(dc_lsize - 1); | 610 | blast_dcache_range(addr, addr + size); |
658 | end = (addr + size - 1) & ~(dc_lsize - 1); | ||
659 | while (1) { | ||
660 | flush_dcache_line(a); /* Hit_Writeback_Inv_D */ | ||
661 | if (a == end) | ||
662 | break; | ||
663 | a += dc_lsize; | ||
664 | } | ||
665 | } | 611 | } |
666 | 612 | ||
667 | bc_wback_inv(addr, size); | 613 | bc_wback_inv(addr, size); |
@@ -669,44 +615,22 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) | |||
669 | 615 | ||
670 | static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) | 616 | static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) |
671 | { | 617 | { |
672 | unsigned long end, a; | ||
673 | |||
674 | /* Catch bad driver code */ | 618 | /* Catch bad driver code */ |
675 | BUG_ON(size == 0); | 619 | BUG_ON(size == 0); |
676 | 620 | ||
677 | if (cpu_has_subset_pcaches) { | 621 | if (cpu_has_subset_pcaches) { |
678 | unsigned long sc_lsize = cpu_scache_line_size(); | 622 | if (size >= scache_size) |
679 | |||
680 | if (size >= scache_size) { | ||
681 | r4k_blast_scache(); | 623 | r4k_blast_scache(); |
682 | return; | 624 | else |
683 | } | 625 | blast_scache_range(addr, addr + size); |
684 | |||
685 | a = addr & ~(sc_lsize - 1); | ||
686 | end = (addr + size - 1) & ~(sc_lsize - 1); | ||
687 | while (1) { | ||
688 | flush_scache_line(a); /* Hit_Writeback_Inv_SD */ | ||
689 | if (a == end) | ||
690 | break; | ||
691 | a += sc_lsize; | ||
692 | } | ||
693 | return; | 626 | return; |
694 | } | 627 | } |
695 | 628 | ||
696 | if (size >= dcache_size) { | 629 | if (size >= dcache_size) { |
697 | r4k_blast_dcache(); | 630 | r4k_blast_dcache(); |
698 | } else { | 631 | } else { |
699 | unsigned long dc_lsize = cpu_dcache_line_size(); | ||
700 | |||
701 | R4600_HIT_CACHEOP_WAR_IMPL; | 632 | R4600_HIT_CACHEOP_WAR_IMPL; |
702 | a = addr & ~(dc_lsize - 1); | 633 | blast_dcache_range(addr, addr + size); |
703 | end = (addr + size - 1) & ~(dc_lsize - 1); | ||
704 | while (1) { | ||
705 | flush_dcache_line(a); /* Hit_Writeback_Inv_D */ | ||
706 | if (a == end) | ||
707 | break; | ||
708 | a += dc_lsize; | ||
709 | } | ||
710 | } | 634 | } |
711 | 635 | ||
712 | bc_inv(addr, size); | 636 | bc_inv(addr, size); |
diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c index 0a97a9434eba..7c572bea4a98 100644 --- a/arch/mips/mm/c-tx39.c +++ b/arch/mips/mm/c-tx39.c | |||
@@ -44,8 +44,6 @@ __asm__ __volatile__( \ | |||
44 | /* TX39H-style cache flush routines. */ | 44 | /* TX39H-style cache flush routines. */ |
45 | static void tx39h_flush_icache_all(void) | 45 | static void tx39h_flush_icache_all(void) |
46 | { | 46 | { |
47 | unsigned long start = KSEG0; | ||
48 | unsigned long end = (start + icache_size); | ||
49 | unsigned long flags, config; | 47 | unsigned long flags, config; |
50 | 48 | ||
51 | /* disable icache (set ICE#) */ | 49 | /* disable icache (set ICE#) */ |
@@ -53,33 +51,18 @@ static void tx39h_flush_icache_all(void) | |||
53 | config = read_c0_conf(); | 51 | config = read_c0_conf(); |
54 | write_c0_conf(config & ~TX39_CONF_ICE); | 52 | write_c0_conf(config & ~TX39_CONF_ICE); |
55 | TX39_STOP_STREAMING(); | 53 | TX39_STOP_STREAMING(); |
56 | 54 | blast_icache16(); | |
57 | /* invalidate icache */ | ||
58 | while (start < end) { | ||
59 | cache16_unroll32(start, Index_Invalidate_I); | ||
60 | start += 0x200; | ||
61 | } | ||
62 | |||
63 | write_c0_conf(config); | 55 | write_c0_conf(config); |
64 | local_irq_restore(flags); | 56 | local_irq_restore(flags); |
65 | } | 57 | } |
66 | 58 | ||
67 | static void tx39h_dma_cache_wback_inv(unsigned long addr, unsigned long size) | 59 | static void tx39h_dma_cache_wback_inv(unsigned long addr, unsigned long size) |
68 | { | 60 | { |
69 | unsigned long end, a; | ||
70 | unsigned long dc_lsize = current_cpu_data.dcache.linesz; | ||
71 | |||
72 | /* Catch bad driver code */ | 61 | /* Catch bad driver code */ |
73 | BUG_ON(size == 0); | 62 | BUG_ON(size == 0); |
74 | 63 | ||
75 | iob(); | 64 | iob(); |
76 | a = addr & ~(dc_lsize - 1); | 65 | blast_inv_dcache_range(addr, addr + size); |
77 | end = (addr + size - 1) & ~(dc_lsize - 1); | ||
78 | while (1) { | ||
79 | invalidate_dcache_line(a); /* Hit_Invalidate_D */ | ||
80 | if (a == end) break; | ||
81 | a += dc_lsize; | ||
82 | } | ||
83 | } | 66 | } |
84 | 67 | ||
85 | 68 | ||
@@ -241,42 +224,21 @@ static void tx39_flush_data_cache_page(unsigned long addr) | |||
241 | 224 | ||
242 | static void tx39_flush_icache_range(unsigned long start, unsigned long end) | 225 | static void tx39_flush_icache_range(unsigned long start, unsigned long end) |
243 | { | 226 | { |
244 | unsigned long dc_lsize = current_cpu_data.dcache.linesz; | ||
245 | unsigned long addr, aend; | ||
246 | |||
247 | if (end - start > dcache_size) | 227 | if (end - start > dcache_size) |
248 | tx39_blast_dcache(); | 228 | tx39_blast_dcache(); |
249 | else { | 229 | else |
250 | addr = start & ~(dc_lsize - 1); | 230 | protected_blast_dcache_range(start, end); |
251 | aend = (end - 1) & ~(dc_lsize - 1); | ||
252 | |||
253 | while (1) { | ||
254 | /* Hit_Writeback_Inv_D */ | ||
255 | protected_writeback_dcache_line(addr); | ||
256 | if (addr == aend) | ||
257 | break; | ||
258 | addr += dc_lsize; | ||
259 | } | ||
260 | } | ||
261 | 231 | ||
262 | if (end - start > icache_size) | 232 | if (end - start > icache_size) |
263 | tx39_blast_icache(); | 233 | tx39_blast_icache(); |
264 | else { | 234 | else { |
265 | unsigned long flags, config; | 235 | unsigned long flags, config; |
266 | addr = start & ~(dc_lsize - 1); | ||
267 | aend = (end - 1) & ~(dc_lsize - 1); | ||
268 | /* disable icache (set ICE#) */ | 236 | /* disable icache (set ICE#) */ |
269 | local_irq_save(flags); | 237 | local_irq_save(flags); |
270 | config = read_c0_conf(); | 238 | config = read_c0_conf(); |
271 | write_c0_conf(config & ~TX39_CONF_ICE); | 239 | write_c0_conf(config & ~TX39_CONF_ICE); |
272 | TX39_STOP_STREAMING(); | 240 | TX39_STOP_STREAMING(); |
273 | while (1) { | 241 | protected_blast_icache_range(start, end); |
274 | /* Hit_Invalidate_I */ | ||
275 | protected_flush_icache_line(addr); | ||
276 | if (addr == aend) | ||
277 | break; | ||
278 | addr += dc_lsize; | ||
279 | } | ||
280 | write_c0_conf(config); | 242 | write_c0_conf(config); |
281 | local_irq_restore(flags); | 243 | local_irq_restore(flags); |
282 | } | 244 | } |
@@ -311,7 +273,7 @@ static void tx39_flush_icache_page(struct vm_area_struct *vma, struct page *page | |||
311 | 273 | ||
312 | static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size) | 274 | static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size) |
313 | { | 275 | { |
314 | unsigned long end, a; | 276 | unsigned long end; |
315 | 277 | ||
316 | if (((size | addr) & (PAGE_SIZE - 1)) == 0) { | 278 | if (((size | addr) & (PAGE_SIZE - 1)) == 0) { |
317 | end = addr + size; | 279 | end = addr + size; |
@@ -322,20 +284,13 @@ static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size) | |||
322 | } else if (size > dcache_size) { | 284 | } else if (size > dcache_size) { |
323 | tx39_blast_dcache(); | 285 | tx39_blast_dcache(); |
324 | } else { | 286 | } else { |
325 | unsigned long dc_lsize = current_cpu_data.dcache.linesz; | 287 | blast_dcache_range(addr, addr + size); |
326 | a = addr & ~(dc_lsize - 1); | ||
327 | end = (addr + size - 1) & ~(dc_lsize - 1); | ||
328 | while (1) { | ||
329 | flush_dcache_line(a); /* Hit_Writeback_Inv_D */ | ||
330 | if (a == end) break; | ||
331 | a += dc_lsize; | ||
332 | } | ||
333 | } | 288 | } |
334 | } | 289 | } |
335 | 290 | ||
336 | static void tx39_dma_cache_inv(unsigned long addr, unsigned long size) | 291 | static void tx39_dma_cache_inv(unsigned long addr, unsigned long size) |
337 | { | 292 | { |
338 | unsigned long end, a; | 293 | unsigned long end; |
339 | 294 | ||
340 | if (((size | addr) & (PAGE_SIZE - 1)) == 0) { | 295 | if (((size | addr) & (PAGE_SIZE - 1)) == 0) { |
341 | end = addr + size; | 296 | end = addr + size; |
@@ -346,14 +301,7 @@ static void tx39_dma_cache_inv(unsigned long addr, unsigned long size) | |||
346 | } else if (size > dcache_size) { | 301 | } else if (size > dcache_size) { |
347 | tx39_blast_dcache(); | 302 | tx39_blast_dcache(); |
348 | } else { | 303 | } else { |
349 | unsigned long dc_lsize = current_cpu_data.dcache.linesz; | 304 | blast_inv_dcache_range(addr, addr + size); |
350 | a = addr & ~(dc_lsize - 1); | ||
351 | end = (addr + size - 1) & ~(dc_lsize - 1); | ||
352 | while (1) { | ||
353 | invalidate_dcache_line(a); /* Hit_Invalidate_D */ | ||
354 | if (a == end) break; | ||
355 | a += dc_lsize; | ||
356 | } | ||
357 | } | 305 | } |
358 | } | 306 | } |
359 | 307 | ||