Merge branch 'core/topology' of git://git.kernel.org/pub/scm/linux/kernel/git/tip...
[pandora-kernel.git] / arch / powerpc / kernel / entry_32.S
index 69a91bd..7231a70 100644 (file)
@@ -30,6 +30,7 @@
 #include <asm/ppc_asm.h>
 #include <asm/asm-offsets.h>
 #include <asm/unistd.h>
+#include <asm/ftrace.h>
 
 #undef SHOW_SYSCALLS
 #undef SHOW_SYSCALLS_TASK
@@ -110,9 +111,9 @@ transfer_to_handler:
        stw     r11,PT_REGS(r12)
 #if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
        /* Check to see if the dbcr0 register is set up to debug.  Use the
-          single-step bit to do this. */
+          internal debug mode bit to do this. */
        lwz     r12,THREAD_DBCR0(r12)
-       andis.  r12,r12,DBCR0_IC@h
+       andis.  r12,r12,DBCR0_IDM@h
        beq+    3f
        /* From user and task is ptraced - load up global dbcr0 */
        li      r12,-1                  /* clear all pending debug events */
@@ -120,6 +121,12 @@ transfer_to_handler:
        lis     r11,global_dbcr0@ha
        tophys(r11,r11)
        addi    r11,r11,global_dbcr0@l
+#ifdef CONFIG_SMP
+       rlwinm  r9,r1,0,0,(31-THREAD_SHIFT)
+       lwz     r9,TI_CPU(r9)
+       slwi    r9,r9,3
+       add     r11,r11,r9
+#endif
        lwz     r12,0(r11)
        mtspr   SPRN_DBCR0,r12
        lwz     r12,4(r11)
@@ -131,11 +138,12 @@ transfer_to_handler:
 2:     /* if from kernel, check interrupted DOZE/NAP mode and
          * check for stack overflow
          */
-       lwz     r9,THREAD_INFO-THREAD(r12)
-       cmplw   r1,r9                   /* if r1 <= current->thread_info */
+       lwz     r9,KSP_LIMIT(r12)
+       cmplw   r1,r9                   /* if r1 <= ksp_limit */
        ble-    stack_ovf               /* then the kernel stack overflowed */
 5:
 #ifdef CONFIG_6xx
+       rlwinm  r9,r1,0,0,31-THREAD_SHIFT
        tophys(r9,r9)                   /* check local flags */
        lwz     r12,TI_LOCAL_FLAGS(r9)
        mtcrf   0x01,r12
@@ -238,10 +246,10 @@ ret_from_syscall:
        stw     r11,_CCR(r1)
 syscall_exit_cont:
 #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
-       /* If the process has its own DBCR0 value, load it up.  The single
-          step bit tells us that dbcr0 should be loaded. */
+       /* If the process has its own DBCR0 value, load it up.  The internal
+          debug mode bit tells us that dbcr0 should be loaded. */
        lwz     r0,THREAD+THREAD_DBCR0(r2)
-       andis.  r10,r0,DBCR0_IC@h
+       andis.  r10,r0,DBCR0_IDM@h
        bnel-   load_dbcr0
 #endif
 #ifdef CONFIG_44x
@@ -666,10 +674,10 @@ user_exc_return:          /* r10 contains MSR_KERNEL here */
 
 restore_user:
 #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
-       /* Check whether this process has its own DBCR0 value.  The single
-          step bit tells us that dbcr0 should be loaded. */
+       /* Check whether this process has its own DBCR0 value.  The internal
+          debug mode bit tells us that dbcr0 should be loaded. */
        lwz     r0,THREAD+THREAD_DBCR0(r2)
-       andis.  r10,r0,DBCR0_IC@h
+       andis.  r10,r0,DBCR0_IDM@h
        bnel-   load_dbcr0
 #endif
 
@@ -879,6 +887,12 @@ load_dbcr0:
        mfspr   r10,SPRN_DBCR0
        lis     r11,global_dbcr0@ha
        addi    r11,r11,global_dbcr0@l
+#ifdef CONFIG_SMP
+       rlwinm  r9,r1,0,0,(31-THREAD_SHIFT)
+       lwz     r9,TI_CPU(r9)
+       slwi    r9,r9,3
+       add     r11,r11,r9
+#endif
        stw     r10,0(r11)
        mtspr   SPRN_DBCR0,r0
        lwz     r10,4(r11)
@@ -891,7 +905,7 @@ load_dbcr0:
        .section .bss
        .align  4
 global_dbcr0:
-       .space  8
+       .space  8*NR_CPUS
        .previous
 #endif /* !(CONFIG_4xx || CONFIG_BOOKE) */
 
@@ -1022,3 +1036,129 @@ machine_check_in_rtas:
        /* XXX load up BATs and panic */
 
 #endif /* CONFIG_PPC_RTAS */
+
+#ifdef CONFIG_FTRACE
+#ifdef CONFIG_DYNAMIC_FTRACE
+_GLOBAL(mcount)
+_GLOBAL(_mcount)
+       stwu    r1,-48(r1)
+       stw     r3, 12(r1)
+       stw     r4, 16(r1)
+       stw     r5, 20(r1)
+       stw     r6, 24(r1)
+       mflr    r3
+       stw     r7, 28(r1)
+       mfcr    r5
+       stw     r8, 32(r1)
+       stw     r9, 36(r1)
+       stw     r10,40(r1)
+       stw     r3, 44(r1)
+       stw     r5, 8(r1)
+       subi    r3, r3, MCOUNT_INSN_SIZE
+       .globl mcount_call
+mcount_call:
+       bl      ftrace_stub
+       nop
+       lwz     r6, 8(r1)
+       lwz     r0, 44(r1)
+       lwz     r3, 12(r1)
+       mtctr   r0
+       lwz     r4, 16(r1)
+       mtcr    r6
+       lwz     r5, 20(r1)
+       lwz     r6, 24(r1)
+       lwz     r0, 52(r1)
+       lwz     r7, 28(r1)
+       lwz     r8, 32(r1)
+       mtlr    r0
+       lwz     r9, 36(r1)
+       lwz     r10,40(r1)
+       addi    r1, r1, 48
+       bctr
+
+_GLOBAL(ftrace_caller)
+       /* Based off of objdump optput from glibc */
+       stwu    r1,-48(r1)
+       stw     r3, 12(r1)
+       stw     r4, 16(r1)
+       stw     r5, 20(r1)
+       stw     r6, 24(r1)
+       mflr    r3
+       lwz     r4, 52(r1)
+       mfcr    r5
+       stw     r7, 28(r1)
+       stw     r8, 32(r1)
+       stw     r9, 36(r1)
+       stw     r10,40(r1)
+       stw     r3, 44(r1)
+       stw     r5, 8(r1)
+       subi    r3, r3, MCOUNT_INSN_SIZE
+.globl ftrace_call
+ftrace_call:
+       bl      ftrace_stub
+       nop
+       lwz     r6, 8(r1)
+       lwz     r0, 44(r1)
+       lwz     r3, 12(r1)
+       mtctr   r0
+       lwz     r4, 16(r1)
+       mtcr    r6
+       lwz     r5, 20(r1)
+       lwz     r6, 24(r1)
+       lwz     r0, 52(r1)
+       lwz     r7, 28(r1)
+       lwz     r8, 32(r1)
+       mtlr    r0
+       lwz     r9, 36(r1)
+       lwz     r10,40(r1)
+       addi    r1, r1, 48
+       bctr
+#else
+_GLOBAL(mcount)
+_GLOBAL(_mcount)
+       stwu    r1,-48(r1)
+       stw     r3, 12(r1)
+       stw     r4, 16(r1)
+       stw     r5, 20(r1)
+       stw     r6, 24(r1)
+       mflr    r3
+       lwz     r4, 52(r1)
+       mfcr    r5
+       stw     r7, 28(r1)
+       stw     r8, 32(r1)
+       stw     r9, 36(r1)
+       stw     r10,40(r1)
+       stw     r3, 44(r1)
+       stw     r5, 8(r1)
+
+       subi    r3, r3, MCOUNT_INSN_SIZE
+       LOAD_REG_ADDR(r5, ftrace_trace_function)
+       lwz     r5,0(r5)
+
+       mtctr   r5
+       bctrl
+
+       nop
+
+       lwz     r6, 8(r1)
+       lwz     r0, 44(r1)
+       lwz     r3, 12(r1)
+       mtctr   r0
+       lwz     r4, 16(r1)
+       mtcr    r6
+       lwz     r5, 20(r1)
+       lwz     r6, 24(r1)
+       lwz     r0, 52(r1)
+       lwz     r7, 28(r1)
+       lwz     r8, 32(r1)
+       mtlr    r0
+       lwz     r9, 36(r1)
+       lwz     r10,40(r1)
+       addi    r1, r1, 48
+       bctr
+#endif
+
+_GLOBAL(ftrace_stub)
+       blr
+
+#endif /* CONFIG_MCOUNT */