aboutsummaryrefslogtreecommitdiffstats
path: root/arch/m68k/kernel/signal_mm.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/m68k/kernel/signal_mm.c')
-rw-r--r--arch/m68k/kernel/signal_mm.c187
1 files changed, 136 insertions, 51 deletions
diff --git a/arch/m68k/kernel/signal_mm.c b/arch/m68k/kernel/signal_mm.c
index 5f6b3d0fcd16..cb856f9da655 100644
--- a/arch/m68k/kernel/signal_mm.c
+++ b/arch/m68k/kernel/signal_mm.c
@@ -203,7 +203,8 @@ static inline int restore_fpu_state(struct sigcontext *sc)
203 203
204 if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) { 204 if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {
205 /* Verify the frame format. */ 205 /* Verify the frame format. */
206 if (!CPU_IS_060 && (sc->sc_fpstate[0] != fpu_version)) 206 if (!(CPU_IS_060 || CPU_IS_COLDFIRE) &&
207 (sc->sc_fpstate[0] != fpu_version))
207 goto out; 208 goto out;
208 if (CPU_IS_020_OR_030) { 209 if (CPU_IS_020_OR_030) {
209 if (m68k_fputype & FPU_68881 && 210 if (m68k_fputype & FPU_68881 &&
@@ -222,19 +223,43 @@ static inline int restore_fpu_state(struct sigcontext *sc)
222 sc->sc_fpstate[3] == 0x60 || 223 sc->sc_fpstate[3] == 0x60 ||
223 sc->sc_fpstate[3] == 0xe0)) 224 sc->sc_fpstate[3] == 0xe0))
224 goto out; 225 goto out;
226 } else if (CPU_IS_COLDFIRE) {
227 if (!(sc->sc_fpstate[0] == 0x00 ||
228 sc->sc_fpstate[0] == 0x05 ||
229 sc->sc_fpstate[0] == 0xe5))
230 goto out;
225 } else 231 } else
226 goto out; 232 goto out;
227 233
228 __asm__ volatile (".chip 68k/68881\n\t" 234 if (CPU_IS_COLDFIRE) {
229 "fmovemx %0,%%fp0-%%fp1\n\t" 235 __asm__ volatile ("fmovemd %0,%%fp0-%%fp1\n\t"
230 "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t" 236 "fmovel %1,%%fpcr\n\t"
231 ".chip 68k" 237 "fmovel %2,%%fpsr\n\t"
232 : /* no outputs */ 238 "fmovel %3,%%fpiar"
233 : "m" (*sc->sc_fpregs), "m" (*sc->sc_fpcntl)); 239 : /* no outputs */
240 : "m" (sc->sc_fpregs[0]),
241 "m" (sc->sc_fpcntl[0]),
242 "m" (sc->sc_fpcntl[1]),
243 "m" (sc->sc_fpcntl[2]));
244 } else {
245 __asm__ volatile (".chip 68k/68881\n\t"
246 "fmovemx %0,%%fp0-%%fp1\n\t"
247 "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t"
248 ".chip 68k"
249 : /* no outputs */
250 : "m" (*sc->sc_fpregs),
251 "m" (*sc->sc_fpcntl));
252 }
253 }
254
255 if (CPU_IS_COLDFIRE) {
256 __asm__ volatile ("frestore %0" : : "m" (*sc->sc_fpstate));
257 } else {
258 __asm__ volatile (".chip 68k/68881\n\t"
259 "frestore %0\n\t"
260 ".chip 68k"
261 : : "m" (*sc->sc_fpstate));
234 } 262 }
235 __asm__ volatile (".chip 68k/68881\n\t"
236 "frestore %0\n\t"
237 ".chip 68k" : : "m" (*sc->sc_fpstate));
238 err = 0; 263 err = 0;
239 264
240out: 265out:
@@ -249,7 +274,7 @@ out:
249static inline int rt_restore_fpu_state(struct ucontext __user *uc) 274static inline int rt_restore_fpu_state(struct ucontext __user *uc)
250{ 275{
251 unsigned char fpstate[FPCONTEXT_SIZE]; 276 unsigned char fpstate[FPCONTEXT_SIZE];
252 int context_size = CPU_IS_060 ? 8 : 0; 277 int context_size = CPU_IS_060 ? 8 : (CPU_IS_COLDFIRE ? 12 : 0);
253 fpregset_t fpregs; 278 fpregset_t fpregs;
254 int err = 1; 279 int err = 1;
255 280
@@ -268,10 +293,11 @@ static inline int rt_restore_fpu_state(struct ucontext __user *uc)
268 if (__get_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate)) 293 if (__get_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate))
269 goto out; 294 goto out;
270 if (CPU_IS_060 ? fpstate[2] : fpstate[0]) { 295 if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {
271 if (!CPU_IS_060) 296 if (!(CPU_IS_060 || CPU_IS_COLDFIRE))
272 context_size = fpstate[1]; 297 context_size = fpstate[1];
273 /* Verify the frame format. */ 298 /* Verify the frame format. */
274 if (!CPU_IS_060 && (fpstate[0] != fpu_version)) 299 if (!(CPU_IS_060 || CPU_IS_COLDFIRE) &&
300 (fpstate[0] != fpu_version))
275 goto out; 301 goto out;
276 if (CPU_IS_020_OR_030) { 302 if (CPU_IS_020_OR_030) {
277 if (m68k_fputype & FPU_68881 && 303 if (m68k_fputype & FPU_68881 &&
@@ -290,26 +316,50 @@ static inline int rt_restore_fpu_state(struct ucontext __user *uc)
290 fpstate[3] == 0x60 || 316 fpstate[3] == 0x60 ||
291 fpstate[3] == 0xe0)) 317 fpstate[3] == 0xe0))
292 goto out; 318 goto out;
319 } else if (CPU_IS_COLDFIRE) {
320 if (!(fpstate[3] == 0x00 ||
321 fpstate[3] == 0x05 ||
322 fpstate[3] == 0xe5))
323 goto out;
293 } else 324 } else
294 goto out; 325 goto out;
295 if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs, 326 if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs,
296 sizeof(fpregs))) 327 sizeof(fpregs)))
297 goto out; 328 goto out;
298 __asm__ volatile (".chip 68k/68881\n\t" 329
299 "fmovemx %0,%%fp0-%%fp7\n\t" 330 if (CPU_IS_COLDFIRE) {
300 "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t" 331 __asm__ volatile ("fmovemd %0,%%fp0-%%fp7\n\t"
301 ".chip 68k" 332 "fmovel %1,%%fpcr\n\t"
302 : /* no outputs */ 333 "fmovel %2,%%fpsr\n\t"
303 : "m" (*fpregs.f_fpregs), 334 "fmovel %3,%%fpiar"
304 "m" (*fpregs.f_fpcntl)); 335 : /* no outputs */
336 : "m" (fpregs.f_fpregs[0]),
337 "m" (fpregs.f_fpcntl[0]),
338 "m" (fpregs.f_fpcntl[1]),
339 "m" (fpregs.f_fpcntl[2]));
340 } else {
341 __asm__ volatile (".chip 68k/68881\n\t"
342 "fmovemx %0,%%fp0-%%fp7\n\t"
343 "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t"
344 ".chip 68k"
345 : /* no outputs */
346 : "m" (*fpregs.f_fpregs),
347 "m" (*fpregs.f_fpcntl));
348 }
305 } 349 }
306 if (context_size && 350 if (context_size &&
307 __copy_from_user(fpstate + 4, (long __user *)&uc->uc_fpstate + 1, 351 __copy_from_user(fpstate + 4, (long __user *)&uc->uc_fpstate + 1,
308 context_size)) 352 context_size))
309 goto out; 353 goto out;
310 __asm__ volatile (".chip 68k/68881\n\t" 354
311 "frestore %0\n\t" 355 if (CPU_IS_COLDFIRE) {
312 ".chip 68k" : : "m" (*fpstate)); 356 __asm__ volatile ("frestore %0" : : "m" (*fpstate));
357 } else {
358 __asm__ volatile (".chip 68k/68881\n\t"
359 "frestore %0\n\t"
360 ".chip 68k"
361 : : "m" (*fpstate));
362 }
313 err = 0; 363 err = 0;
314 364
315out: 365out:
@@ -529,10 +579,15 @@ static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)
529 return; 579 return;
530 } 580 }
531 581
532 __asm__ volatile (".chip 68k/68881\n\t" 582 if (CPU_IS_COLDFIRE) {
533 "fsave %0\n\t" 583 __asm__ volatile ("fsave %0"
534 ".chip 68k" 584 : : "m" (*sc->sc_fpstate) : "memory");
535 : : "m" (*sc->sc_fpstate) : "memory"); 585 } else {
586 __asm__ volatile (".chip 68k/68881\n\t"
587 "fsave %0\n\t"
588 ".chip 68k"
589 : : "m" (*sc->sc_fpstate) : "memory");
590 }
536 591
537 if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) { 592 if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {
538 fpu_version = sc->sc_fpstate[0]; 593 fpu_version = sc->sc_fpstate[0];
@@ -543,21 +598,35 @@ static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)
543 if (*(unsigned short *) sc->sc_fpstate == 0x1f38) 598 if (*(unsigned short *) sc->sc_fpstate == 0x1f38)
544 sc->sc_fpstate[0x38] |= 1 << 3; 599 sc->sc_fpstate[0x38] |= 1 << 3;
545 } 600 }
546 __asm__ volatile (".chip 68k/68881\n\t" 601
547 "fmovemx %%fp0-%%fp1,%0\n\t" 602 if (CPU_IS_COLDFIRE) {
548 "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t" 603 __asm__ volatile ("fmovemd %%fp0-%%fp1,%0\n\t"
549 ".chip 68k" 604 "fmovel %%fpcr,%1\n\t"
550 : "=m" (*sc->sc_fpregs), 605 "fmovel %%fpsr,%2\n\t"
551 "=m" (*sc->sc_fpcntl) 606 "fmovel %%fpiar,%3"
552 : /* no inputs */ 607 : "=m" (sc->sc_fpregs[0]),
553 : "memory"); 608 "=m" (sc->sc_fpcntl[0]),
609 "=m" (sc->sc_fpcntl[1]),
610 "=m" (sc->sc_fpcntl[2])
611 : /* no inputs */
612 : "memory");
613 } else {
614 __asm__ volatile (".chip 68k/68881\n\t"
615 "fmovemx %%fp0-%%fp1,%0\n\t"
616 "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t"
617 ".chip 68k"
618 : "=m" (*sc->sc_fpregs),
619 "=m" (*sc->sc_fpcntl)
620 : /* no inputs */
621 : "memory");
622 }
554 } 623 }
555} 624}
556 625
557static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *regs) 626static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *regs)
558{ 627{
559 unsigned char fpstate[FPCONTEXT_SIZE]; 628 unsigned char fpstate[FPCONTEXT_SIZE];
560 int context_size = CPU_IS_060 ? 8 : 0; 629 int context_size = CPU_IS_060 ? 8 : (CPU_IS_COLDFIRE ? 12 : 0);
561 int err = 0; 630 int err = 0;
562 631
563 if (FPU_IS_EMU) { 632 if (FPU_IS_EMU) {
@@ -570,15 +639,19 @@ static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *
570 return err; 639 return err;
571 } 640 }
572 641
573 __asm__ volatile (".chip 68k/68881\n\t" 642 if (CPU_IS_COLDFIRE) {
574 "fsave %0\n\t" 643 __asm__ volatile ("fsave %0" : : "m" (*fpstate) : "memory");
575 ".chip 68k" 644 } else {
576 : : "m" (*fpstate) : "memory"); 645 __asm__ volatile (".chip 68k/68881\n\t"
646 "fsave %0\n\t"
647 ".chip 68k"
648 : : "m" (*fpstate) : "memory");
649 }
577 650
578 err |= __put_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate); 651 err |= __put_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate);
579 if (CPU_IS_060 ? fpstate[2] : fpstate[0]) { 652 if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {
580 fpregset_t fpregs; 653 fpregset_t fpregs;
581 if (!CPU_IS_060) 654 if (!(CPU_IS_060 || CPU_IS_COLDFIRE))
582 context_size = fpstate[1]; 655 context_size = fpstate[1];
583 fpu_version = fpstate[0]; 656 fpu_version = fpstate[0];
584 if (CPU_IS_020_OR_030 && 657 if (CPU_IS_020_OR_030 &&
@@ -588,14 +661,27 @@ static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *
588 if (*(unsigned short *) fpstate == 0x1f38) 661 if (*(unsigned short *) fpstate == 0x1f38)
589 fpstate[0x38] |= 1 << 3; 662 fpstate[0x38] |= 1 << 3;
590 } 663 }
591 __asm__ volatile (".chip 68k/68881\n\t" 664 if (CPU_IS_COLDFIRE) {
592 "fmovemx %%fp0-%%fp7,%0\n\t" 665 __asm__ volatile ("fmovemd %%fp0-%%fp7,%0\n\t"
593 "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t" 666 "fmovel %%fpcr,%1\n\t"
594 ".chip 68k" 667 "fmovel %%fpsr,%2\n\t"
595 : "=m" (*fpregs.f_fpregs), 668 "fmovel %%fpiar,%3"
596 "=m" (*fpregs.f_fpcntl) 669 : "=m" (fpregs.f_fpregs[0]),
597 : /* no inputs */ 670 "=m" (fpregs.f_fpcntl[0]),
598 : "memory"); 671 "=m" (fpregs.f_fpcntl[1]),
672 "=m" (fpregs.f_fpcntl[2])
673 : /* no inputs */
674 : "memory");
675 } else {
676 __asm__ volatile (".chip 68k/68881\n\t"
677 "fmovemx %%fp0-%%fp7,%0\n\t"
678 "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t"
679 ".chip 68k"
680 : "=m" (*fpregs.f_fpregs),
681 "=m" (*fpregs.f_fpcntl)
682 : /* no inputs */
683 : "memory");
684 }
599 err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs, 685 err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs,
600 sizeof(fpregs)); 686 sizeof(fpregs));
601 } 687 }
@@ -692,8 +778,7 @@ static inline void push_cache (unsigned long vaddr)
692 "cpushl %%bc,(%0)\n\t" 778 "cpushl %%bc,(%0)\n\t"
693 ".chip 68k" 779 ".chip 68k"
694 : : "a" (temp)); 780 : : "a" (temp));
695 } 781 } else if (!CPU_IS_COLDFIRE) {
696 else {
697 /* 782 /*
698 * 68030/68020 have no writeback cache; 783 * 68030/68020 have no writeback cache;
699 * still need to clear icache. 784 * still need to clear icache.