aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/m68k/kernel/traps.c104
1 files changed, 104 insertions, 0 deletions
diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c
index 89362f2bb56a..a76452ca964e 100644
--- a/arch/m68k/kernel/traps.c
+++ b/arch/m68k/kernel/traps.c
@@ -706,6 +706,88 @@ create_atc_entry:
706#endif /* CPU_M68020_OR_M68030 */ 706#endif /* CPU_M68020_OR_M68030 */
707#endif /* !CONFIG_SUN3 */ 707#endif /* !CONFIG_SUN3 */
708 708
709#if defined(CONFIG_COLDFIRE) && defined(CONFIG_MMU)
710#include <asm/mcfmmu.h>
711
712/*
713 * The following table converts the FS encoding of a ColdFire
714 * exception stack frame into the error_code value needed by
715 * do_fault.
716*/
717static const unsigned char fs_err_code[] = {
718 0, /* 0000 */
719 0, /* 0001 */
720 0, /* 0010 */
721 0, /* 0011 */
722 1, /* 0100 */
723 0, /* 0101 */
724 0, /* 0110 */
725 0, /* 0111 */
726 2, /* 1000 */
727 3, /* 1001 */
728 2, /* 1010 */
729 0, /* 1011 */
730 1, /* 1100 */
731 1, /* 1101 */
732 0, /* 1110 */
733 0 /* 1111 */
734};
735
736static inline void access_errorcf(unsigned int fs, struct frame *fp)
737{
738 unsigned long mmusr, addr;
739 unsigned int err_code;
740 int need_page_fault;
741
742 mmusr = mmu_read(MMUSR);
743 addr = mmu_read(MMUAR);
744
745 /*
746 * error_code:
747 * bit 0 == 0 means no page found, 1 means protection fault
748 * bit 1 == 0 means read, 1 means write
749 */
750 switch (fs) {
751 case 5: /* 0101 TLB opword X miss */
752 need_page_fault = cf_tlb_miss(&fp->ptregs, 0, 0, 0);
753 addr = fp->ptregs.pc;
754 break;
755 case 6: /* 0110 TLB extension word X miss */
756 need_page_fault = cf_tlb_miss(&fp->ptregs, 0, 0, 1);
757 addr = fp->ptregs.pc + sizeof(long);
758 break;
759 case 10: /* 1010 TLB W miss */
760 need_page_fault = cf_tlb_miss(&fp->ptregs, 1, 1, 0);
761 break;
762 case 14: /* 1110 TLB R miss */
763 need_page_fault = cf_tlb_miss(&fp->ptregs, 0, 1, 0);
764 break;
765 default:
766 /* 0000 Normal */
767 /* 0001 Reserved */
768 /* 0010 Interrupt during debug service routine */
769 /* 0011 Reserved */
770 /* 0100 X Protection */
771 /* 0111 IFP in emulator mode */
772 /* 1000 W Protection*/
773 /* 1001 Write error*/
774 /* 1011 Reserved*/
775 /* 1100 R Protection*/
776 /* 1101 R Protection*/
777 /* 1111 OEP in emulator mode*/
778 need_page_fault = 1;
779 break;
780 }
781
782 if (need_page_fault) {
783 err_code = fs_err_code[fs];
784 if ((fs == 13) && (mmusr & MMUSR_WF)) /* rd-mod-wr access */
785 err_code |= 2; /* bit1 - write, bit0 - protection */
786 do_page_fault(&fp->ptregs, addr, err_code);
787 }
788}
789#endif /* CONFIG_COLDFIRE CONFIG_MMU */
790
709asmlinkage void buserr_c(struct frame *fp) 791asmlinkage void buserr_c(struct frame *fp)
710{ 792{
711 /* Only set esp0 if coming from user mode */ 793 /* Only set esp0 if coming from user mode */
@@ -716,6 +798,28 @@ asmlinkage void buserr_c(struct frame *fp)
716 printk ("*** Bus Error *** Format is %x\n", fp->ptregs.format); 798 printk ("*** Bus Error *** Format is %x\n", fp->ptregs.format);
717#endif 799#endif
718 800
801#if defined(CONFIG_COLDFIRE) && defined(CONFIG_MMU)
802 if (CPU_IS_COLDFIRE) {
803 unsigned int fs;
804 fs = (fp->ptregs.vector & 0x3) |
805 ((fp->ptregs.vector & 0xc00) >> 8);
806 switch (fs) {
807 case 0x5:
808 case 0x6:
809 case 0x7:
810 case 0x9:
811 case 0xa:
812 case 0xd:
813 case 0xe:
814 case 0xf:
815 access_errorcf(fs, fp);
816 return;
817 default:
818 break;
819 }
820 }
821#endif /* CONFIG_COLDFIRE && CONFIG_MMU */
822
719 switch (fp->ptregs.format) { 823 switch (fp->ptregs.format) {
720#if defined (CONFIG_M68060) 824#if defined (CONFIG_M68060)
721 case 4: /* 68060 access error */ 825 case 4: /* 68060 access error */