~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to arch/powerpc/lib/sstep.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
#include <linux/kernel.h>
12
12
#include <linux/kprobes.h>
13
13
#include <linux/ptrace.h>
 
14
#include <linux/prefetch.h>
14
15
#include <asm/sstep.h>
15
16
#include <asm/processor.h>
16
17
#include <asm/uaccess.h>
45
46
#endif
46
47
 
47
48
/*
 
49
 * Emulate the truncation of 64 bit values in 32-bit mode.
 
50
 */
 
51
static unsigned long truncate_if_32bit(unsigned long msr, unsigned long val)
 
52
{
 
53
#ifdef __powerpc64__
 
54
        if ((msr & MSR_64BIT) == 0)
 
55
                val &= 0xffffffffUL;
 
56
#endif
 
57
        return val;
 
58
}
 
59
 
 
60
/*
48
61
 * Determine whether a conditional branch instruction would branch.
49
62
 */
50
63
static int __kprobes branch_taken(unsigned int instr, struct pt_regs *regs)
90
103
                if (instr & 0x04000000)         /* update forms */
91
104
                        regs->gpr[ra] = ea;
92
105
        }
93
 
#ifdef __powerpc64__
94
 
        if (!(regs->msr & MSR_SF))
95
 
                ea &= 0xffffffffUL;
96
 
#endif
97
 
        return ea;
 
106
 
 
107
        return truncate_if_32bit(regs->msr, ea);
98
108
}
99
109
 
100
110
#ifdef __powerpc64__
113
123
                if ((instr & 3) == 1)           /* update forms */
114
124
                        regs->gpr[ra] = ea;
115
125
        }
116
 
        if (!(regs->msr & MSR_SF))
117
 
                ea &= 0xffffffffUL;
118
 
        return ea;
 
126
 
 
127
        return truncate_if_32bit(regs->msr, ea);
119
128
}
120
129
#endif /* __powerpc64 */
121
130
 
136
145
                if (do_update)          /* update forms */
137
146
                        regs->gpr[ra] = ea;
138
147
        }
139
 
#ifdef __powerpc64__
140
 
        if (!(regs->msr & MSR_SF))
141
 
                ea &= 0xffffffffUL;
142
 
#endif
143
 
        return ea;
 
148
 
 
149
        return truncate_if_32bit(regs->msr, ea);
144
150
}
145
151
 
146
152
/*
466
472
 
467
473
        regs->ccr = (regs->ccr & 0x0fffffff) | ((regs->xer >> 3) & 0x10000000);
468
474
#ifdef __powerpc64__
469
 
        if (!(regs->msr & MSR_SF))
 
475
        if (!(regs->msr & MSR_64BIT))
470
476
                val = (int) val;
471
477
#endif
472
478
        if (val < 0)
487
493
                ++val;
488
494
        regs->gpr[rd] = val;
489
495
#ifdef __powerpc64__
490
 
        if (!(regs->msr & MSR_SF)) {
 
496
        if (!(regs->msr & MSR_64BIT)) {
491
497
                val = (unsigned int) val;
492
498
                val1 = (unsigned int) val1;
493
499
        }
570
576
                if ((instr & 2) == 0)
571
577
                        imm += regs->nip;
572
578
                regs->nip += 4;
573
 
                if ((regs->msr & MSR_SF) == 0)
574
 
                        regs->nip &= 0xffffffffUL;
 
579
                regs->nip = truncate_if_32bit(regs->msr, regs->nip);
575
580
                if (instr & 1)
576
581
                        regs->link = regs->nip;
577
582
                if (branch_taken(instr, regs))
604
609
                        imm -= 0x04000000;
605
610
                if ((instr & 2) == 0)
606
611
                        imm += regs->nip;
607
 
                if (instr & 1) {
608
 
                        regs->link = regs->nip + 4;
609
 
                        if ((regs->msr & MSR_SF) == 0)
610
 
                                regs->link &= 0xffffffffUL;
611
 
                }
612
 
                if ((regs->msr & MSR_SF) == 0)
613
 
                        imm &= 0xffffffffUL;
 
612
                if (instr & 1)
 
613
                        regs->link = truncate_if_32bit(regs->msr, regs->nip + 4);
 
614
                imm = truncate_if_32bit(regs->msr, imm);
614
615
                regs->nip = imm;
615
616
                return 1;
616
617
        case 19:
618
619
                case 16:        /* bclr */
619
620
                case 528:       /* bcctr */
620
621
                        imm = (instr & 0x400)? regs->ctr: regs->link;
621
 
                        regs->nip += 4;
622
 
                        if ((regs->msr & MSR_SF) == 0) {
623
 
                                regs->nip &= 0xffffffffUL;
624
 
                                imm &= 0xffffffffUL;
625
 
                        }
 
622
                        regs->nip = truncate_if_32bit(regs->msr, regs->nip + 4);
 
623
                        imm = truncate_if_32bit(regs->msr, imm);
626
624
                        if (instr & 1)
627
625
                                regs->link = regs->nip;
628
626
                        if (branch_taken(instr, regs))
1616
1614
                return 0;       /* invoke DSI if -EFAULT? */
1617
1615
        }
1618
1616
 instr_done:
1619
 
        regs->nip += 4;
1620
 
#ifdef __powerpc64__
1621
 
        if ((regs->msr & MSR_SF) == 0)
1622
 
                regs->nip &= 0xffffffffUL;
1623
 
#endif
 
1617
        regs->nip = truncate_if_32bit(regs->msr, regs->nip + 4);
1624
1618
        return 1;
1625
1619
 
1626
1620
 logical_done: