diff options
-rw-r--r-- | arch/m68k/kernel/traps.c | 104 |
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 | */ | ||
717 | static 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 | |||
736 | static 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 | |||
709 | asmlinkage void buserr_c(struct frame *fp) | 791 | asmlinkage 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 */ |