diff options
Diffstat (limited to 'arch/powerpc/kernel/traps.c')
-rw-r--r-- | arch/powerpc/kernel/traps.c | 58 |
1 files changed, 18 insertions, 40 deletions
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 5457e9575685..970d66ec4657 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <asm/processor.h> | 52 | #include <asm/processor.h> |
53 | #endif | 53 | #endif |
54 | #include <asm/kexec.h> | 54 | #include <asm/kexec.h> |
55 | #include <asm/ppc-opcode.h> | ||
55 | 56 | ||
56 | #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) | 57 | #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) |
57 | int (*__debugger)(struct pt_regs *regs); | 58 | int (*__debugger)(struct pt_regs *regs); |
@@ -637,29 +638,6 @@ static void parse_fpe(struct pt_regs *regs) | |||
637 | * bits is faster and easier. | 638 | * bits is faster and easier. |
638 | * | 639 | * |
639 | */ | 640 | */ |
640 | #define INST_MFSPR_PVR 0x7c1f42a6 | ||
641 | #define INST_MFSPR_PVR_MASK 0xfc1fffff | ||
642 | |||
643 | #define INST_DCBA 0x7c0005ec | ||
644 | #define INST_DCBA_MASK 0xfc0007fe | ||
645 | |||
646 | #define INST_MCRXR 0x7c000400 | ||
647 | #define INST_MCRXR_MASK 0xfc0007fe | ||
648 | |||
649 | #define INST_STRING 0x7c00042a | ||
650 | #define INST_STRING_MASK 0xfc0007fe | ||
651 | #define INST_STRING_GEN_MASK 0xfc00067e | ||
652 | #define INST_LSWI 0x7c0004aa | ||
653 | #define INST_LSWX 0x7c00042a | ||
654 | #define INST_STSWI 0x7c0005aa | ||
655 | #define INST_STSWX 0x7c00052a | ||
656 | |||
657 | #define INST_POPCNTB 0x7c0000f4 | ||
658 | #define INST_POPCNTB_MASK 0xfc0007fe | ||
659 | |||
660 | #define INST_ISEL 0x7c00001e | ||
661 | #define INST_ISEL_MASK 0xfc00003e | ||
662 | |||
663 | static int emulate_string_inst(struct pt_regs *regs, u32 instword) | 641 | static int emulate_string_inst(struct pt_regs *regs, u32 instword) |
664 | { | 642 | { |
665 | u8 rT = (instword >> 21) & 0x1f; | 643 | u8 rT = (instword >> 21) & 0x1f; |
@@ -670,20 +648,20 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword) | |||
670 | int pos = 0; | 648 | int pos = 0; |
671 | 649 | ||
672 | /* Early out if we are an invalid form of lswx */ | 650 | /* Early out if we are an invalid form of lswx */ |
673 | if ((instword & INST_STRING_MASK) == INST_LSWX) | 651 | if ((instword & PPC_INST_STRING_MASK) == PPC_INST_LSWX) |
674 | if ((rT == rA) || (rT == NB_RB)) | 652 | if ((rT == rA) || (rT == NB_RB)) |
675 | return -EINVAL; | 653 | return -EINVAL; |
676 | 654 | ||
677 | EA = (rA == 0) ? 0 : regs->gpr[rA]; | 655 | EA = (rA == 0) ? 0 : regs->gpr[rA]; |
678 | 656 | ||
679 | switch (instword & INST_STRING_MASK) { | 657 | switch (instword & PPC_INST_STRING_MASK) { |
680 | case INST_LSWX: | 658 | case PPC_INST_LSWX: |
681 | case INST_STSWX: | 659 | case PPC_INST_STSWX: |
682 | EA += NB_RB; | 660 | EA += NB_RB; |
683 | num_bytes = regs->xer & 0x7f; | 661 | num_bytes = regs->xer & 0x7f; |
684 | break; | 662 | break; |
685 | case INST_LSWI: | 663 | case PPC_INST_LSWI: |
686 | case INST_STSWI: | 664 | case PPC_INST_STSWI: |
687 | num_bytes = (NB_RB == 0) ? 32 : NB_RB; | 665 | num_bytes = (NB_RB == 0) ? 32 : NB_RB; |
688 | break; | 666 | break; |
689 | default: | 667 | default: |
@@ -695,9 +673,9 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword) | |||
695 | u8 val; | 673 | u8 val; |
696 | u32 shift = 8 * (3 - (pos & 0x3)); | 674 | u32 shift = 8 * (3 - (pos & 0x3)); |
697 | 675 | ||
698 | switch ((instword & INST_STRING_MASK)) { | 676 | switch ((instword & PPC_INST_STRING_MASK)) { |
699 | case INST_LSWX: | 677 | case PPC_INST_LSWX: |
700 | case INST_LSWI: | 678 | case PPC_INST_LSWI: |
701 | if (get_user(val, (u8 __user *)EA)) | 679 | if (get_user(val, (u8 __user *)EA)) |
702 | return -EFAULT; | 680 | return -EFAULT; |
703 | /* first time updating this reg, | 681 | /* first time updating this reg, |
@@ -706,8 +684,8 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword) | |||
706 | regs->gpr[rT] = 0; | 684 | regs->gpr[rT] = 0; |
707 | regs->gpr[rT] |= val << shift; | 685 | regs->gpr[rT] |= val << shift; |
708 | break; | 686 | break; |
709 | case INST_STSWI: | 687 | case PPC_INST_STSWI: |
710 | case INST_STSWX: | 688 | case PPC_INST_STSWX: |
711 | val = regs->gpr[rT] >> shift; | 689 | val = regs->gpr[rT] >> shift; |
712 | if (put_user(val, (u8 __user *)EA)) | 690 | if (put_user(val, (u8 __user *)EA)) |
713 | return -EFAULT; | 691 | return -EFAULT; |
@@ -775,18 +753,18 @@ static int emulate_instruction(struct pt_regs *regs) | |||
775 | return -EFAULT; | 753 | return -EFAULT; |
776 | 754 | ||
777 | /* Emulate the mfspr rD, PVR. */ | 755 | /* Emulate the mfspr rD, PVR. */ |
778 | if ((instword & INST_MFSPR_PVR_MASK) == INST_MFSPR_PVR) { | 756 | if ((instword & PPC_INST_MFSPR_PVR_MASK) == PPC_INST_MFSPR_PVR) { |
779 | rd = (instword >> 21) & 0x1f; | 757 | rd = (instword >> 21) & 0x1f; |
780 | regs->gpr[rd] = mfspr(SPRN_PVR); | 758 | regs->gpr[rd] = mfspr(SPRN_PVR); |
781 | return 0; | 759 | return 0; |
782 | } | 760 | } |
783 | 761 | ||
784 | /* Emulating the dcba insn is just a no-op. */ | 762 | /* Emulating the dcba insn is just a no-op. */ |
785 | if ((instword & INST_DCBA_MASK) == INST_DCBA) | 763 | if ((instword & PPC_INST_DCBA_MASK) == PPC_INST_DCBA) |
786 | return 0; | 764 | return 0; |
787 | 765 | ||
788 | /* Emulate the mcrxr insn. */ | 766 | /* Emulate the mcrxr insn. */ |
789 | if ((instword & INST_MCRXR_MASK) == INST_MCRXR) { | 767 | if ((instword & PPC_INST_MCRXR_MASK) == PPC_INST_MCRXR) { |
790 | int shift = (instword >> 21) & 0x1c; | 768 | int shift = (instword >> 21) & 0x1c; |
791 | unsigned long msk = 0xf0000000UL >> shift; | 769 | unsigned long msk = 0xf0000000UL >> shift; |
792 | 770 | ||
@@ -796,16 +774,16 @@ static int emulate_instruction(struct pt_regs *regs) | |||
796 | } | 774 | } |
797 | 775 | ||
798 | /* Emulate load/store string insn. */ | 776 | /* Emulate load/store string insn. */ |
799 | if ((instword & INST_STRING_GEN_MASK) == INST_STRING) | 777 | if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING) |
800 | return emulate_string_inst(regs, instword); | 778 | return emulate_string_inst(regs, instword); |
801 | 779 | ||
802 | /* Emulate the popcntb (Population Count Bytes) instruction. */ | 780 | /* Emulate the popcntb (Population Count Bytes) instruction. */ |
803 | if ((instword & INST_POPCNTB_MASK) == INST_POPCNTB) { | 781 | if ((instword & PPC_INST_POPCNTB_MASK) == PPC_INST_POPCNTB) { |
804 | return emulate_popcntb_inst(regs, instword); | 782 | return emulate_popcntb_inst(regs, instword); |
805 | } | 783 | } |
806 | 784 | ||
807 | /* Emulate isel (Integer Select) instruction */ | 785 | /* Emulate isel (Integer Select) instruction */ |
808 | if ((instword & INST_ISEL_MASK) == INST_ISEL) { | 786 | if ((instword & PPC_INST_ISEL_MASK) == PPC_INST_ISEL) { |
809 | return emulate_isel(regs, instword); | 787 | return emulate_isel(regs, instword); |
810 | } | 788 | } |
811 | 789 | ||