diff options
author | Kumar Gala <galak@kernel.crashing.org> | 2009-02-10 20:10:44 +0000 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-02-23 10:48:56 +1100 |
commit | 16c57b3620d77e0bc981da5ef32beae730512684 (patch) | |
tree | 115045916a264f56f55751ce2948d59e03b16c0c /arch/powerpc/kernel | |
parent | bb9b903527eb16c8fdad59a562c29e89f5dcf233 (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.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/entry_32.S | 8 | ||||
-rw-r--r-- | arch/powerpc/kernel/ftrace.c | 8 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_booke.h | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/module_64.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/traps.c | 58 |
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) * branch to "addr" we jump to ("addr" + 32 MB). Although it requires * two instructions it doesn't require any registers. */ - patch_instruction(p, PPC_NOP_INSTR); + patch_instruction(p, PPC_INST_NOP); patch_branch(++p, addr + PHYSICAL_START, 0); } 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: lwz r10,crit_srr1@l(r10); mtspr SPRN_SRR0,r9; mtspr SPRN_SRR1,r10; - RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI) + RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, PPC_RFCI) #endif /* CONFIG_40x */ #ifdef CONFIG_BOOKE @@ -967,7 +967,7 @@ ret_from_crit_exc: stw r10,KSP_LIMIT(r9) RESTORE_xSRR(SRR0,SRR1); RESTORE_MMU_REGS; - RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, RFCI) + RET_FROM_EXC_LEVEL(SPRN_CSRR0, SPRN_CSRR1, PPC_RFCI) .globl ret_from_debug_exc ret_from_debug_exc: @@ -981,7 +981,7 @@ ret_from_debug_exc: RESTORE_xSRR(SRR0,SRR1); RESTORE_xSRR(CSRR0,CSRR1); RESTORE_MMU_REGS; - RET_FROM_EXC_LEVEL(SPRN_DSRR0, SPRN_DSRR1, RFDI) + RET_FROM_EXC_LEVEL(SPRN_DSRR0, SPRN_DSRR1, PPC_RFDI) .globl ret_from_mcheck_exc ret_from_mcheck_exc: @@ -992,7 +992,7 @@ ret_from_mcheck_exc: RESTORE_xSRR(CSRR0,CSRR1); RESTORE_xSRR(DSRR0,DSRR1); RESTORE_MMU_REGS; - RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, RFMCI) + RET_FROM_EXC_LEVEL(SPRN_MCSRR0, SPRN_MCSRR1, PPC_RFMCI) #endif /* CONFIG_BOOKE */ /* 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 @@ #ifdef CONFIG_DYNAMIC_FTRACE static unsigned int ftrace_nop_replace(void) { - return PPC_NOP_INSTR; + return PPC_INST_NOP; } static unsigned int @@ -302,7 +302,7 @@ __ftrace_make_nop(struct module *mod, return -EINVAL; } - op = PPC_NOP_INSTR; + op = PPC_INST_NOP; if (probe_kernel_write((void *)ip, &op, MCOUNT_INSN_SIZE)) return -EPERM; @@ -380,7 +380,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) * b +8; ld r2,40(r1) */ if (((op[0] != 0x48000008) || (op[1] != 0xe8410028)) && - ((op[0] != PPC_NOP_INSTR) || (op[1] != PPC_NOP_INSTR))) { + ((op[0] != PPC_INST_NOP) || (op[1] != PPC_INST_NOP))) { printk(KERN_ERR "Expected NOPs but have %x %x\n", op[0], op[1]); return -EINVAL; } @@ -423,7 +423,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) return -EFAULT; /* It should be pointing to a nop */ - if (op != PPC_NOP_INSTR) { + if (op != PPC_INST_NOP) { printk(KERN_ERR "Expected NOP but have %x\n", op); return -EINVAL; } 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: lwz r11,GPR11(r8); \ mfspr r8,DEBUG_SPRG; \ \ - RFDI; \ + PPC_RFDI; \ b .; \ \ /* 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, restore r2. */ static int restore_r2(u32 *instruction, struct module *me) { - if (*instruction != PPC_NOP_INSTR) { + if (*instruction != PPC_INST_NOP) { printk("%s: Expect noop after relocate, got %08x\n", me->name, *instruction); 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 @@ #include <asm/processor.h> #endif #include <asm/kexec.h> +#include <asm/ppc-opcode.h> #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) int (*__debugger)(struct pt_regs *regs); @@ -637,29 +638,6 @@ static void parse_fpe(struct pt_regs *regs) * bits is faster and easier. * */ -#define INST_MFSPR_PVR 0x7c1f42a6 -#define INST_MFSPR_PVR_MASK 0xfc1fffff - -#define INST_DCBA 0x7c0005ec -#define INST_DCBA_MASK 0xfc0007fe - -#define INST_MCRXR 0x7c000400 -#define INST_MCRXR_MASK 0xfc0007fe - -#define INST_STRING 0x7c00042a -#define INST_STRING_MASK 0xfc0007fe -#define INST_STRING_GEN_MASK 0xfc00067e -#define INST_LSWI 0x7c0004aa -#define INST_LSWX 0x7c00042a -#define INST_STSWI 0x7c0005aa -#define INST_STSWX 0x7c00052a - -#define INST_POPCNTB 0x7c0000f4 -#define INST_POPCNTB_MASK 0xfc0007fe - -#define INST_ISEL 0x7c00001e -#define INST_ISEL_MASK 0xfc00003e - static int emulate_string_inst(struct pt_regs *regs, u32 instword) { u8 rT = (instword >> 21) & 0x1f; @@ -670,20 +648,20 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword) int pos = 0; /* Early out if we are an invalid form of lswx */ - if ((instword & INST_STRING_MASK) == INST_LSWX) + if ((instword & PPC_INST_STRING_MASK) == PPC_INST_LSWX) if ((rT == rA) || (rT == NB_RB)) return -EINVAL; EA = (rA == 0) ? 0 : regs->gpr[rA]; - switch (instword & INST_STRING_MASK) { - case INST_LSWX: - case INST_STSWX: + switch (instword & PPC_INST_STRING_MASK) { + case PPC_INST_LSWX: + case PPC_INST_STSWX: EA += NB_RB; num_bytes = regs->xer & 0x7f; break; - case INST_LSWI: - case INST_STSWI: + case PPC_INST_LSWI: + case PPC_INST_STSWI: num_bytes = (NB_RB == 0) ? 32 : NB_RB; break; default: @@ -695,9 +673,9 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword) u8 val; u32 shift = 8 * (3 - (pos & 0x3)); - switch ((instword & INST_STRING_MASK)) { - case INST_LSWX: - case INST_LSWI: + switch ((instword & PPC_INST_STRING_MASK)) { + case PPC_INST_LSWX: + case PPC_INST_LSWI: if (get_user(val, (u8 __user *)EA)) return -EFAULT; /* first time updating this reg, @@ -706,8 +684,8 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword) regs->gpr[rT] = 0; regs->gpr[rT] |= val << shift; break; - case INST_STSWI: - case INST_STSWX: + case PPC_INST_STSWI: + case PPC_INST_STSWX: val = regs->gpr[rT] >> shift; if (put_user(val, (u8 __user *)EA)) return -EFAULT; @@ -775,18 +753,18 @@ static int emulate_instruction(struct pt_regs *regs) return -EFAULT; /* Emulate the mfspr rD, PVR. */ - if ((instword & INST_MFSPR_PVR_MASK) == INST_MFSPR_PVR) { + if ((instword & PPC_INST_MFSPR_PVR_MASK) == PPC_INST_MFSPR_PVR) { rd = (instword >> 21) & 0x1f; regs->gpr[rd] = mfspr(SPRN_PVR); return 0; } /* Emulating the dcba insn is just a no-op. */ - if ((instword & INST_DCBA_MASK) == INST_DCBA) + if ((instword & PPC_INST_DCBA_MASK) == PPC_INST_DCBA) return 0; /* Emulate the mcrxr insn. */ - if ((instword & INST_MCRXR_MASK) == INST_MCRXR) { + if ((instword & PPC_INST_MCRXR_MASK) == PPC_INST_MCRXR) { int shift = (instword >> 21) & 0x1c; unsigned long msk = 0xf0000000UL >> shift; @@ -796,16 +774,16 @@ static int emulate_instruction(struct pt_regs *regs) } /* Emulate load/store string insn. */ - if ((instword & INST_STRING_GEN_MASK) == INST_STRING) + if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING) return emulate_string_inst(regs, instword); /* Emulate the popcntb (Population Count Bytes) instruction. */ - if ((instword & INST_POPCNTB_MASK) == INST_POPCNTB) { + if ((instword & PPC_INST_POPCNTB_MASK) == PPC_INST_POPCNTB) { return emulate_popcntb_inst(regs, instword); } /* Emulate isel (Integer Select) instruction */ - if ((instword & INST_ISEL_MASK) == INST_ISEL) { + if ((instword & PPC_INST_ISEL_MASK) == PPC_INST_ISEL) { return emulate_isel(regs, instword); } |