11 #include <linux/module.h>
12 #include <linux/sched.h>
13 #include <linux/kernel.h>
14 #include <linux/string.h>
15 #include <linux/errno.h>
16 #include <linux/ptrace.h>
24 #include <linux/pci.h>
25 #include <asm/processor.h>
26 #include <asm/uaccess.h>
30 #include <asm/pgalloc.h>
32 #include <asm/busctl-regs.h>
34 #include <asm/gdb-stub.h>
35 #include <asm/asm-offsets.h>
38 #define kdebug(FMT, ...) printk(KERN_DEBUG "MISALIGN: "FMT"\n", ##__VA_ARGS__)
40 #define kdebug(FMT, ...) do {} while (0)
43 static int misalignment_addr(
unsigned long *
registers,
unsigned long sp,
46 void **_address,
unsigned long **_postinc,
50 unsigned opcode,
unsigned long disp,
51 unsigned long **_register);
55 static const unsigned Dreg_index[] = {
56 REG_D0 >> 2, REG_D1 >> 2, REG_D2 >> 2, REG_D3 >> 2
59 static const unsigned Areg_index[] = {
60 REG_A0 >> 2, REG_A1 >> 2,
REG_A2 >> 2, REG_A3 >> 2
63 static const unsigned Rreg_index[] = {
64 REG_E0 >> 2, REG_E1 >> 2, REG_E2 >> 2, REG_E3 >> 2,
65 REG_E4 >> 2, REG_E5 >> 2, REG_E6 >> 2, REG_E7 >> 2,
66 REG_A0 >> 2, REG_A1 >> 2,
REG_A2 >> 2, REG_A3 >> 2,
67 REG_D0 >> 2, REG_D1 >> 2, REG_D2 >> 2, REG_D3 >> 2
164 #define MEM(ADDR) (0x80000000 | (ADDR))
165 #define MEM2(ADDR1, ADDR2) (0x80000000 | (ADDR1) << 8 | (ADDR2))
166 #define MEMINC(ADDR) (0x81000000 | (ADDR))
167 #define MEMINC2(ADDR, INC) (0x81000000 | (ADDR) << 8 | (INC))
311 {
"", 0, 0, 0, 0, 0, {0}},
321 unsigned long *
registers = (
unsigned long *) regs;
334 sp = (
unsigned long) regs +
sizeof(*regs);
336 kdebug(
"==>misalignment({pc=%lx,sp=%lx})", regs->
pc, sp);
338 if (regs->
epsw & EPSW_IE)
339 asm volatile(
"or %0,epsw" : :
"i"(EPSW_IE));
354 for (pop = mn10300_opcodes; pop->
name[0]; pop++) {
356 if (npop <= 0 || npop > 31)
358 npop = (npop + 8) & ~7;
364 }
else if (npop > noc) {
365 xo = pop->
opcode >> (npop - noc);
366 xm = pop->
opmask >> (npop - noc);
368 if ((opcode & xm) != xo)
376 opcode = opcode << 8 |
byte;
400 info.si_addr = (
void *) regs->
pc;
407 "MISALIGN: %p: fault whilst reading instruction data\n",
413 "MISALIGN: %lx: unsupported addressing mode %x\n",
419 "MISALIGN: %lx: unsupported register mode %x\n",
423 unsupported_instruction:
425 "MISALIGN: %lx: unsupported instruction %x (%s)\n",
426 regs->
pc, opcode, pop->
name);
441 info.si_addr = (
void *) regs->
pc;
447 kdebug(
"%lx: %x==%x { %x, %x }",
450 tmp = format_tbl[pop->
format].opsz;
461 dispsz = format_tbl[pop->
format].dispsz;
462 for (loop = 0; loop <
dispsz; loop += 8) {
466 disp |= byte << loop;
467 kdebug(
"{%p} disp[%02x]=%02x", pc, loop, byte);
479 "MISALIGN: %lx: insn not move to/from memory %x\n",
485 if (pop->
name[3] == 0 ||
488 else if (pop->
name[3] ==
'h')
491 goto unsupported_instruction;
493 if (pop->
params[0] & 0x80000000) {
495 if (!misalignment_addr(registers, sp,
496 pop->
params[0], opcode, disp,
497 &address, &postinc, &inc))
500 if (!misalignment_reg(registers, pop->
params[1], opcode, disp,
504 kdebug(
"mov%u (%p),DARn", datasz, address);
506 goto transfer_failed;
507 if (pop->
params[0] & 0x1000000) {
513 kdebug(
"loaded %lx", data);
516 if (!misalignment_reg(registers, pop->
params[0], opcode, disp,
520 if (!misalignment_addr(registers, sp,
521 pop->
params[1], opcode, disp,
522 &address, &postinc, &inc))
527 kdebug(
"mov%u %lx,(%p)", datasz, data, address);
529 goto transfer_failed;
530 if (pop->
params[1] & 0x1000000)
534 tmp = format_tbl[pop->
format].opsz + format_tbl[pop->
format].dispsz;
535 regs->
pc += tmp >> 3;
540 misalignment_MOV_Lcc(regs, opcode);
548 static int misalignment_addr(
unsigned long *
registers,
unsigned long sp,
551 void **_address,
unsigned long **_postinc,
556 if (!(params & 0x1000000)) {
562 params &= 0x00ffffff;
565 switch (params & 0xff) {
567 postinc = ®isters[Dreg_index[opcode & 0x03]];
571 postinc = ®isters[Dreg_index[opcode >> 2 & 0x03]];
575 postinc = ®isters[Dreg_index[opcode >> 4 & 0x03]];
579 postinc = ®isters[Areg_index[opcode & 0x03]];
583 postinc = ®isters[Areg_index[opcode >> 2 & 0x03]];
587 postinc = ®isters[Areg_index[opcode >> 4 & 0x03]];
591 postinc = ®isters[Rreg_index[opcode & 0x0f]];
595 postinc = ®isters[Rreg_index[opcode >> 2 & 0x0f]];
599 postinc = ®isters[Rreg_index[opcode >> 4 & 0x0f]];
603 postinc = ®isters[Rreg_index[opcode >> 8 & 0x0f]];
607 postinc = ®isters[Rreg_index[opcode >> 12 & 0x0f]];
611 postinc = ®isters[Rreg_index[disp & 0x0f]];
615 postinc = ®isters[Rreg_index[disp >> 4 & 0x0f]];
628 goto displace_or_inc;
631 goto displace_or_inc;
634 asm(
"asr 8,%0" :
"=r"(
tmp) :
"0"(
tmp) :
"cc");
636 goto displace_or_inc;
638 tmp = opcode >> 4 & 0x0f;
640 asm(
"asr 28,%0" :
"=r"(
tmp) :
"0"(
tmp) :
"cc");
642 goto displace_or_inc;
645 goto displace_or_inc;
648 goto displace_or_inc;
651 goto displace_or_inc;
657 kdebug(
"%s %lx", _inc ?
"incr" :
"disp", disp);
667 }
while ((params >>= 8));
669 *_address = (
void *) address;
677 static int misalignment_reg(
unsigned long *registers,
unsigned params,
678 unsigned opcode,
unsigned long disp,
679 unsigned long **_register)
681 params &= 0x7fffffff;
683 if (params & 0xffffff00)
686 switch (params & 0xff) {
688 *_register = ®isters[Dreg_index[opcode & 0x03]];
691 *_register = ®isters[Dreg_index[opcode >> 2 & 0x03]];
694 *_register = ®isters[Dreg_index[opcode >> 4 & 0x03]];
697 *_register = ®isters[Areg_index[opcode & 0x03]];
700 *_register = ®isters[Areg_index[opcode >> 2 & 0x03]];
703 *_register = ®isters[Areg_index[opcode >> 4 & 0x03]];
706 *_register = ®isters[Rreg_index[opcode & 0x0f]];
709 *_register = ®isters[Rreg_index[opcode >> 2 & 0x0f]];
712 *_register = ®isters[Rreg_index[opcode >> 4 & 0x0f]];
715 *_register = ®isters[Rreg_index[opcode >> 8 & 0x0f]];
718 *_register = ®isters[Rreg_index[opcode >> 12 & 0x0f]];
721 *_register = ®isters[Rreg_index[disp & 0x0f]];
724 *_register = ®isters[Rreg_index[disp >> 4 & 0x0f]];
727 *_register = ®isters[
REG_SP >> 2];
743 unsigned long epsw = regs->
epsw;
746 kdebug(
"MOV_Lcc %x [flags=%lx]", opcode, epsw & 0xf);
749 NxorV = ((epsw >> 3) ^ epsw >> 1) & 1;
751 switch (opcode & 0xf) {
757 if (!((epsw & EPSW_FLAG_Z) | NxorV))
765 if ((epsw & EPSW_FLAG_Z) | NxorV)
770 if (epsw & EPSW_FLAG_C)
774 if (!(epsw & (EPSW_FLAG_C | EPSW_FLAG_Z)))
778 if (!(epsw & EPSW_FLAG_C))
782 if (epsw & (EPSW_FLAG_C | EPSW_FLAG_Z))
787 if (epsw & EPSW_FLAG_Z)
791 if (!(epsw & EPSW_FLAG_Z))
804 regs->
pc = regs->
lar - 4;
810 #ifdef CONFIG_TEST_MISALIGNMENT_HANDLER
818 #define ASSERTCMP(X, OP, Y) \
820 if (unlikely(!((X) OP (Y)))) { \
821 printk(KERN_ERR "\n"); \
822 printk(KERN_ERR "MISALIGN: Assertion failed at line %u\n", \
824 printk(KERN_ERR "0x%lx " #OP " 0x%lx is false\n", \
825 (unsigned long)(X), (unsigned long)(Y)); \
830 static int __init test_misalignment(
void)
832 register void *
r asm(
"e0");
833 register u32 y asm(
"e1");
834 void *
p = testbuf, *
q;
842 asm volatile(
"mov (%0),%1" :
"+a"(
q),
"=d"(x));
848 asm volatile(
"mov (256,%0),%1" :
"+a"(
q),
"=d"(x));
855 asm volatile(
"mov (%2,%0),%1" :
"+a"(
q),
"=d"(x),
"+d"(
tmp));
862 asm volatile(
"mov (256,%0),%1" :
"+r"(
r),
"=r"(
y));
868 asm volatile(
"mov (%0+),%1" :
"+r"(
r),
"=r"(
y));
874 asm volatile(
"mov (%0+,8),%1" :
"+r"(
r),
"=r"(
y));
888 "movbu %0,(10,sp) \n"
898 "movbu %0,(259,sp) \n"
900 "movbu %0,(260,sp) \n"
902 "movbu %0,(261,sp) \n"
904 "movbu %0,(262,sp) \n"
907 :
"+d"(
tmp),
"=d"(x));
914 "movbu %0,(260,sp) \n"
916 "movbu %0,(261,sp) \n"
918 "movbu %0,(262,sp) \n"
920 "movbu %0,(263,sp) \n"
923 :
"+d"(
tmp),
"=d"(x));
937 :
"+r"(
q),
"+d"(tmp),
"+d"(tmp2),
"=d"(x)
953 :
"+a"(
q),
"+d"(tmp),
"+d"(tmp2),
"=d"(x)