aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorKumar Gala <galak@kernel.crashing.org>2009-02-10 15:10:44 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-02-22 18:48:56 -0500
commit16c57b3620d77e0bc981da5ef32beae730512684 (patch)
tree115045916a264f56f55751ce2948d59e03b16c0c /arch/powerpc/kernel
parentbb9b903527eb16c8fdad59a562c29e89f5dcf233 (diff)
powerpc: Unify opcode definitions and support
Create a new header that becomes a single location for defining PowerPC opcodes used by code that is either generationg instructions at runtime (fixups, debug, etc.), emulating instructions, or just compiling instructions old assemblers don't know about. We currently don't handle the floating point emulation or alignment decode as both are better handled by the specific decode support they already have. Added support for the new dcbzl, dcbal, msgsnd, tlbilx, & wait instructions since older assemblers don't know about them. Signed-off-by: Kumar Gala <galak@kernel.crashing.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/crash_dump.c2
-rw-r--r--arch/powerpc/kernel/entry_32.S8
-rw-r--r--arch/powerpc/kernel/ftrace.c8
-rw-r--r--arch/powerpc/kernel/head_booke.h2
-rw-r--r--arch/powerpc/kernel/module_64.c2
-rw-r--r--arch/powerpc/kernel/traps.c58
6 files changed, 29 insertions, 51 deletions
diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c
index 19671aca6591..5fb667a60894 100644
--- a/arch/powerpc/kernel/crash_dump.c
+++ b/arch/powerpc/kernel/crash_dump.c
@@ -48,7 +48,7 @@ static void __init create_trampoline(unsigned long addr)
48 * branch to "addr" we jump to ("addr" + 32 MB). Although it requires 48 * branch to "addr" we jump to ("addr" + 32 MB). Although it requires
49 * two instructions it doesn't require any registers. 49 * two instructions it doesn't require any registers.
50 */ 50 */
51 patch_instruction(p, PPC_NOP_INSTR); 51 patch_instruction(p, PPC_INST_NOP);
52 patch_branch(++p, addr + PHYSICAL_START, 0); 52 patch_branch(++p, addr + PHYSICAL_START, 0);
53} 53}
54 54
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 0506f54b4237..4dd38f129153 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -956,7 +956,7 @@ ret_from_crit_exc:
956 lwz r10,crit_srr1@l(r10); 956 lwz r10,crit_srr1@l(r10);
957 mtspr SPRN_SRR0,r9; 957 mtspr SPRN_SRR0,r9;
958 mtspr SPRN_SRR1,r10; 958 mtspr SPRN_SRR1,r10;
959 RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI) 959 RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, PPC_RFCI)
960#endif /* CONFIG_40x */ 960#endif /* CONFIG_40x */
961 961
962#ifdef CONFIG_BOOKE 962#ifdef CONFIG_BOOKE
@@ -967,7 +967,7 @@ ret_from_crit_exc:
967 stw r10,KSP_LIMIT(r9) 967 stw r10,KSP_LIMIT(r9)
968 RESTORE_xSRR(SRR0,SRR1); 968 RESTORE_xSRR(SRR0,SRR1);
969 RESTORE_MMU_REGS; 969 RESTORE_MMU_REGS;
970 RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI) 970 RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, PPC_RFCI)
971 971
972 .globl ret_from_debug_exc 972 .globl ret_from_debug_exc
973ret_from_debug_exc: 973ret_from_debug_exc:
@@ -981,7 +981,7 @@ ret_from_debug_exc:
981 RESTORE_xSRR(SRR0,SRR1); 981 RESTORE_xSRR(SRR0,SRR1);
982 RESTORE_xSRR(CSRR0,CSRR1); 982 RESTORE_xSRR(CSRR0,CSRR1);
983 RESTORE_MMU_REGS; 983 RESTORE_MMU_REGS;
984 RET_FROM_EXC_LEVEL(SPRN_DSRR0, SPRN_DSRR1, RFDI) 984 RET_FROM_EXC_LEVEL(SPRN_DSRR0, SPRN_DSRR1, PPC_RFDI)
985 985
986 .globl ret_from_mcheck_exc 986 .globl ret_from_mcheck_exc
987ret_from_mcheck_exc: 987ret_from_mcheck_exc:
@@ -992,7 +992,7 @@ ret_from_mcheck_exc:
992 RESTORE_xSRR(CSRR0,CSRR1); 992 RESTORE_xSRR(CSRR0,CSRR1);
993 RESTORE_xSRR(DSRR0,DSRR1); 993 RESTORE_xSRR(DSRR0,DSRR1);
994 RESTORE_MMU_REGS; 994 RESTORE_MMU_REGS;
995 RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, RFMCI) 995 RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, PPC_RFMCI)
996#endif /* CONFIG_BOOKE */ 996#endif /* CONFIG_BOOKE */
997 997
998/* 998/*
diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c
index 4c75a1c0a5b4..5b5d16b2cac8 100644
--- a/arch/powerpc/kernel/ftrace.c
+++ b/arch/powerpc/kernel/ftrace.c
@@ -33,7 +33,7 @@
33#ifdef CONFIG_DYNAMIC_FTRACE 33#ifdef CONFIG_DYNAMIC_FTRACE
34static unsigned int ftrace_nop_replace(void) 34static unsigned int ftrace_nop_replace(void)
35{ 35{
36 return PPC_NOP_INSTR; 36 return PPC_INST_NOP;
37} 37}
38 38
39static unsigned int 39static unsigned int
@@ -302,7 +302,7 @@ __ftrace_make_nop(struct module *mod,
302 return -EINVAL; 302 return -EINVAL;
303 } 303 }
304 304
305 op = PPC_NOP_INSTR; 305 op = PPC_INST_NOP;
306 306
307 if (probe_kernel_write((void *)ip, &op, MCOUNT_INSN_SIZE)) 307 if (probe_kernel_write((void *)ip, &op, MCOUNT_INSN_SIZE))
308 return -EPERM; 308 return -EPERM;
@@ -380,7 +380,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
380 * b +8; ld r2,40(r1) 380 * b +8; ld r2,40(r1)
381 */ 381 */
382 if (((op[0] != 0x48000008) || (op[1] != 0xe8410028)) && 382 if (((op[0] != 0x48000008) || (op[1] != 0xe8410028)) &&
383 ((op[0] != PPC_NOP_INSTR) || (op[1] != PPC_NOP_INSTR))) { 383 ((op[0] != PPC_INST_NOP) || (op[1] != PPC_INST_NOP))) {
384 printk(KERN_ERR "Expected NOPs but have %x %x\n", op[0], op[1]); 384 printk(KERN_ERR "Expected NOPs but have %x %x\n", op[0], op[1]);
385 return -EINVAL; 385 return -EINVAL;
386 } 386 }
@@ -423,7 +423,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
423 return -EFAULT; 423 return -EFAULT;
424 424
425 /* It should be pointing to a nop */ 425 /* It should be pointing to a nop */
426 if (op != PPC_NOP_INSTR) { 426 if (op != PPC_INST_NOP) {
427 printk(KERN_ERR "Expected NOP but have %x\n", op); 427 printk(KERN_ERR "Expected NOP but have %x\n", op);
428 return -EINVAL; 428 return -EINVAL;
429 } 429 }
diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h
index bec18078239d..38e242eb0ef8 100644
--- a/arch/powerpc/kernel/head_booke.h
+++ b/arch/powerpc/kernel/head_booke.h
@@ -279,7 +279,7 @@ label:
279 lwz r11,GPR11(r8); \ 279 lwz r11,GPR11(r8); \
280 mfspr r8,DEBUG_SPRG; \ 280 mfspr r8,DEBUG_SPRG; \
281 \ 281 \
282 RFDI; \ 282 PPC_RFDI; \
283 b .; \ 283 b .; \
284 \ 284 \
285 /* continue normal handling for a debug exception... */ \ 285 /* continue normal handling for a debug exception... */ \
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index 8992b031a7b6..8fbb12508bf3 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -329,7 +329,7 @@ static unsigned long stub_for_addr(Elf64_Shdr *sechdrs,
329 restore r2. */ 329 restore r2. */
330static int restore_r2(u32 *instruction, struct module *me) 330static int restore_r2(u32 *instruction, struct module *me)
331{ 331{
332 if (*instruction != PPC_NOP_INSTR) { 332 if (*instruction != PPC_INST_NOP) {
333 printk("%s: Expect noop after relocate, got %08x\n", 333 printk("%s: Expect noop after relocate, got %08x\n",
334 me->name, *instruction); 334 me->name, *instruction);
335 return 0; 335 return 0;
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)
57int (*__debugger)(struct pt_regs *regs); 58int (*__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
663static int emulate_string_inst(struct pt_regs *regs, u32 instword) 641static 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