#include <asm/psw.h>
+#include <asm/cache.h> /* for L1_CACHE_SHIFT */
#include <asm/assembly.h> /* for LDREG/STREG defines */
#include <asm/pgtable.h>
#include <asm/signal.h>
#include <asm/unistd.h>
#include <asm/thread_info.h>
+#include <linux/linkage.h>
+
#ifdef CONFIG_64BIT
#define CMPIB cmpib,*
#define CMPB cmpb,*
bb,>=,n \pmd,_PxD_PRESENT_BIT,\fault
DEP %r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */
copy \pmd,%r9
-#ifdef CONFIG_64BIT
- shld %r9,PxD_VALUE_SHIFT,\pmd
-#else
- shlw %r9,PxD_VALUE_SHIFT,\pmd
-#endif
+ SHLREG %r9,PxD_VALUE_SHIFT,\pmd
EXTR \va,31-PAGE_SHIFT,ASM_BITS_PER_PTE,\index
DEP %r0,31,PAGE_SHIFT,\pmd /* clear offset */
shladd \index,BITS_PER_PTE_ENTRY,\pmd,\pmd
* the static part of the kernel address space.
*/
- .export fault_vector_20
-
.text
.align 4096
-fault_vector_20:
+ENTRY(fault_vector_20)
/* First vector is invalid (0) */
.ascii "cows can fly"
.byte 0
def 29
def 30
def 31
+END(fault_vector_20)
#ifndef CONFIG_64BIT
- .export fault_vector_11
-
.align 2048
-fault_vector_11:
+ENTRY(fault_vector_11)
/* First vector is invalid (0) */
.ascii "cows can fly"
.byte 0
def 29
def 30
def 31
+END(fault_vector_11)
#endif
#define CLONE_VM 0x100 /* Must agree with <linux/sched.h> */
#define CLONE_UNTRACED 0x00800000
- .export __kernel_thread, code
.import do_fork
-__kernel_thread:
+ENTRY(__kernel_thread)
STREG %r2, -RP_OFFSET(%r30)
copy %r30, %r1
ldo -PT_SZ_ALGN(%r30), %r30
bv %r0(%r2)
nop
+ENDPROC(__kernel_thread)
/*
* Child Returns here
* into task save area.
*/
- .export ret_from_kernel_thread
-ret_from_kernel_thread:
+ENTRY(ret_from_kernel_thread)
/* Call schedule_tail first though */
BL schedule_tail, %r2
bv %r0(%r1)
#endif
ldi 0, %r26
+ENDPROC(ret_from_kernel_thread)
.import sys_execve, code
- .export __execve, code
-__execve:
+ENTRY(__execve)
copy %r2, %r15
copy %r30, %r16
ldo PT_SZ_ALGN(%r30), %r30
copy %r16, %r30
bv %r0(%r2)
nop
+ENDPROC(__execve)
- .align 4
/*
* struct task_struct *_switch_to(struct task_struct *prev,
* struct task_struct *next)
*
* switch kernel stacks and return prev */
- .export _switch_to, code
-_switch_to:
+ENTRY(_switch_to)
STREG %r2, -RP_OFFSET(%r30)
callee_save_float
LDREG -RP_OFFSET(%r30), %r2
bv %r0(%r2)
copy %r26, %r28
+ENDPROC(_switch_to)
/*
* Common rfi return path for interruptions, kernel execve, and
.align 4096
- .export syscall_exit_rfi
-syscall_exit_rfi:
+ENTRY(syscall_exit_rfi)
mfctl %cr30,%r16
LDREG TI_TASK(%r16), %r16 /* thread_info -> task_struct */
ldo TASK_REGS(%r16),%r16
/* NOTE: Need to enable interrupts incase we schedule. */
ssm PSW_SM_I, %r0
- /* Check for software interrupts */
-
- .import irq_stat,data
-
- load32 irq_stat,%r19
-#ifdef CONFIG_SMP
- mfctl %cr30,%r1
- ldw TI_CPU(%r1),%r1 /* get cpu # - int */
- /* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) amount
- ** irq_stat[] is defined using ____cacheline_aligned.
- */
-#ifdef CONFIG_64BIT
- shld %r1, 6, %r20
-#else
- shlw %r1, 5, %r20
-#endif
- add %r19,%r20,%r19 /* now have &irq_stat[smp_processor_id()] */
-#endif /* CONFIG_SMP */
-
intr_check_resched:
/* check for reschedule */
LDREG TI_FLAGS(%r1),%r19 /* sched.h: TIF_NEED_RESCHED */
bb,<,n %r19,31-TIF_NEED_RESCHED,intr_do_resched /* forward */
+ .import do_notify_resume,code
intr_check_sig:
/* As above */
mfctl %cr30,%r1
- LDREG TI_FLAGS(%r1),%r19 /* sched.h: TIF_SIGPENDING */
- bb,<,n %r19, 31-TIF_SIGPENDING, intr_do_signal /* forward */
+ LDREG TI_FLAGS(%r1),%r19
+ ldi (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK), %r20
+ and,COND(<>) %r19, %r20, %r0
+ b,n intr_restore /* skip past if we've nothing to do */
+
+ /* This check is critical to having LWS
+ * working. The IASQ is zero on the gateway
+ * page and we cannot deliver any signals until
+ * we get off the gateway page.
+ *
+ * Only do signals if we are returning to user space
+ */
+ LDREG PT_IASQ0(%r16), %r20
+ CMPIB=,n 0,%r20,intr_restore /* backward */
+ LDREG PT_IASQ1(%r16), %r20
+ CMPIB=,n 0,%r20,intr_restore /* backward */
+
+ copy %r0, %r25 /* long in_syscall = 0 */
+#ifdef CONFIG_64BIT
+ ldo -16(%r30),%r29 /* Reference param save area */
+#endif
+
+ BL do_notify_resume,%r2
+ copy %r16, %r26 /* struct pt_regs *regs */
+
+ b,n intr_check_sig
intr_restore:
copy %r16,%r29
BL preempt_schedule_irq, %r2
nop
- b intr_restore /* ssm PSW_SM_I done by intr_restore */
+ b,n intr_restore /* ssm PSW_SM_I done by intr_restore */
#endif /* CONFIG_PREEMPT */
- .import do_signal,code
-intr_do_signal:
- /*
- This check is critical to having LWS
- working. The IASQ is zero on the gateway
- page and we cannot deliver any signals until
- we get off the gateway page.
-
- Only do signals if we are returning to user space
- */
- LDREG PT_IASQ0(%r16), %r20
- CMPIB= 0,%r20,intr_restore /* backward */
- nop
- LDREG PT_IASQ1(%r16), %r20
- CMPIB= 0,%r20,intr_restore /* backward */
- nop
-
- copy %r0, %r24 /* unsigned long in_syscall */
- copy %r16, %r25 /* struct pt_regs *regs */
-#ifdef CONFIG_64BIT
- ldo -16(%r30),%r29 /* Reference param save area */
-#endif
-
- BL do_signal,%r2
- copy %r0, %r26 /* sigset_t *oldset = NULL */
-
- b intr_check_sig
- nop
-
/*
* External interrupts.
*/
mfctl %cr31,%r1
copy %r30,%r17
/* FIXME! depi below has hardcoded idea of interrupt stack size (32k)*/
-#ifdef CONFIG_64BIT
- depdi 0,63,15,%r17
-#else
- depi 0,31,15,%r17
-#endif
+ DEPI 0,31,15,%r17
CMPB=,n %r1,%r17,2f
get_stack_use_cr31
b,n 3f
b do_cpu_irq_mask
ldo R%intr_return(%r2), %r2 /* return to intr_return, not here */
+ENDPROC(syscall_exit_rfi)
/* Generic interruptions (illegal insn, unaligned, page fault, etc) */
- .export intr_save, code /* for os_hpmc */
-
-intr_save:
+ENTRY(intr_save) /* for os_hpmc */
mfsp %sr7,%r16
CMPIB=,n 0,%r16,1f
get_stack_use_cr30
b handle_interruption
ldo R%intr_check_sig(%r2), %r2
+ENDPROC(intr_save)
/*
LDREG PT_GR18(\regs),%r18
.endm
- .export sys_fork_wrapper
- .export child_return
-sys_fork_wrapper:
+ENTRY(sys_fork_wrapper)
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
ldo TASK_REGS(%r1),%r1
reg_save %r1
ldi __NR_fork,%r20
bv %r0(%r2)
STREG %r20,PT_GR20(%r1)
+ENDPROC(sys_fork_wrapper)
/* Set the return value for the child */
-child_return:
+ENTRY(child_return)
BL schedule_tail, %r2
nop
LDREG TASK_PT_GR19(%r1),%r2
b wrapper_exit
copy %r0,%r28
+ENDPROC(child_return)
-
- .export sys_clone_wrapper
-sys_clone_wrapper:
+
+ENTRY(sys_clone_wrapper)
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
ldo TASK_REGS(%r1),%r1 /* get pt regs */
reg_save %r1
b wrapper_exit
LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2
+ENDPROC(sys_clone_wrapper)
+
- .export sys_vfork_wrapper
-sys_vfork_wrapper:
+ENTRY(sys_vfork_wrapper)
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
ldo TASK_REGS(%r1),%r1 /* get pt regs */
reg_save %r1
b wrapper_exit
LDREG -RP_OFFSET-FRAME_SIZE(%r30),%r2
+ENDPROC(sys_vfork_wrapper)
.macro execve_wrapper execve
nop
.endm
- .export sys_execve_wrapper
.import sys_execve
-
-sys_execve_wrapper:
+ENTRY(sys_execve_wrapper)
execve_wrapper sys_execve
+ENDPROC(sys_execve_wrapper)
#ifdef CONFIG_64BIT
- .export sys32_execve_wrapper
.import sys32_execve
-
-sys32_execve_wrapper:
+ENTRY(sys32_execve_wrapper)
execve_wrapper sys32_execve
+ENDPROC(sys32_execve_wrapper)
#endif
- .export sys_rt_sigreturn_wrapper
-sys_rt_sigreturn_wrapper:
+ENTRY(sys_rt_sigreturn_wrapper)
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26
ldo TASK_REGS(%r26),%r26 /* get pt regs */
/* Don't save regs, we are going to restore them from sigcontext. */
*/
bv %r0(%r2)
LDREG PT_GR28(%r1),%r28 /* reload original r28 for syscall_exit */
+ENDPROC(sys_rt_sigreturn_wrapper)
- .export sys_sigaltstack_wrapper
-sys_sigaltstack_wrapper:
+ENTRY(sys_sigaltstack_wrapper)
/* Get the user stack pointer */
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
ldo TASK_REGS(%r1),%r24 /* get pt regs */
STREG %r2, -RP_OFFSET(%r30)
#ifdef CONFIG_64BIT
ldo FRAME_SIZE(%r30), %r30
- b,l do_sigaltstack,%r2
+ BL do_sigaltstack,%r2
ldo -16(%r30),%r29 /* Reference param save area */
#else
- bl do_sigaltstack,%r2
+ BL do_sigaltstack,%r2
ldo FRAME_SIZE(%r30), %r30
#endif
LDREG -RP_OFFSET(%r30), %r2
bv %r0(%r2)
nop
+ENDPROC(sys_sigaltstack_wrapper)
#ifdef CONFIG_64BIT
- .export sys32_sigaltstack_wrapper
-sys32_sigaltstack_wrapper:
+ENTRY(sys32_sigaltstack_wrapper)
/* Get the user stack pointer */
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r24
LDREG TASK_PT_GR30(%r24),%r24
STREG %r2, -RP_OFFSET(%r30)
ldo FRAME_SIZE(%r30), %r30
- b,l do_sigaltstack32,%r2
+ BL do_sigaltstack32,%r2
ldo -16(%r30),%r29 /* Reference param save area */
ldo -FRAME_SIZE(%r30), %r30
LDREG -RP_OFFSET(%r30), %r2
bv %r0(%r2)
nop
+ENDPROC(sys32_sigaltstack_wrapper)
#endif
- .export sys_rt_sigsuspend_wrapper
-sys_rt_sigsuspend_wrapper:
- LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
- ldo TASK_REGS(%r1),%r24
- reg_save %r24
-
- STREG %r2, -RP_OFFSET(%r30)
-#ifdef CONFIG_64BIT
- ldo FRAME_SIZE(%r30), %r30
- b,l sys_rt_sigsuspend,%r2
- ldo -16(%r30),%r29 /* Reference param save area */
-#else
- bl sys_rt_sigsuspend,%r2
- ldo FRAME_SIZE(%r30), %r30
-#endif
-
- ldo -FRAME_SIZE(%r30), %r30
- LDREG -RP_OFFSET(%r30), %r2
-
- LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1
- ldo TASK_REGS(%r1),%r1
- reg_restore %r1
-
- bv %r0(%r2)
- nop
-
- .export syscall_exit
-syscall_exit:
-
+ENTRY(syscall_exit)
/* NOTE: HP-UX syscalls also come through here
* after hpux_syscall_exit fixes up return
* values. */
*/
loadgp
-syscall_check_bh:
+syscall_check_resched:
- /* Check for software interrupts */
+ /* check for reschedule */
- .import irq_stat,data
+ LDREG TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19 /* long */
+ bb,<,n %r19, 31-TIF_NEED_RESCHED, syscall_do_resched /* forward */
- load32 irq_stat,%r19
+ .import do_signal,code
+syscall_check_sig:
+ LDREG TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19
+ ldi (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK), %r26
+ and,COND(<>) %r19, %r26, %r0
+ b,n syscall_restore /* skip past if we've nothing to do */
-#ifdef CONFIG_SMP
- /* sched.h: int processor */
- /* %r26 is used as scratch register to index into irq_stat[] */
- ldw TI_CPU-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26 /* cpu # */
+syscall_do_signal:
+ /* Save callee-save registers (for sigcontext).
+ * FIXME: After this point the process structure should be
+ * consistent with all the relevant state of the process
+ * before the syscall. We need to verify this.
+ */
+ LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
+ ldo TASK_REGS(%r1), %r26 /* struct pt_regs *regs */
+ reg_save %r26
- /* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) bits */
#ifdef CONFIG_64BIT
- shld %r26, 6, %r20
-#else
- shlw %r26, 5, %r20
+ ldo -16(%r30),%r29 /* Reference param save area */
#endif
- add %r19,%r20,%r19 /* now have &irq_stat[smp_processor_id()] */
-#endif /* CONFIG_SMP */
-syscall_check_resched:
-
- /* check for reschedule */
+ BL do_notify_resume,%r2
+ ldi 1, %r25 /* long in_syscall = 1 */
- LDREG TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19 /* long */
- bb,<,n %r19, 31-TIF_NEED_RESCHED, syscall_do_resched /* forward */
+ LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
+ ldo TASK_REGS(%r1), %r20 /* reload pt_regs */
+ reg_restore %r20
-syscall_check_sig:
- LDREG TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19 /* get ti flags */
- bb,<,n %r19, 31-TIF_SIGPENDING, syscall_do_signal /* forward */
+ b,n syscall_check_sig
syscall_restore:
/* Are we being ptraced? */
#else
nop
#endif
- b syscall_check_bh /* if resched, we start over again */
+ b syscall_check_resched /* if resched, we start over again */
nop
+ENDPROC(syscall_exit)
- .import do_signal,code
-syscall_do_signal:
- /* Save callee-save registers (for sigcontext).
- FIXME: After this point the process structure should be
- consistent with all the relevant state of the process
- before the syscall. We need to verify this. */
- LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
- ldo TASK_REGS(%r1), %r25 /* struct pt_regs *regs */
- reg_save %r25
-
- ldi 1, %r24 /* unsigned long in_syscall */
-
-#ifdef CONFIG_64BIT
- ldo -16(%r30),%r29 /* Reference param save area */
-#endif
- BL do_signal,%r2
- copy %r0, %r26 /* sigset_t *oldset = NULL */
-
- LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
- ldo TASK_REGS(%r1), %r20 /* reload pt_regs */
- reg_restore %r20
-
- b,n syscall_check_sig
+get_register:
/*
* get_register is used by the non access tlb miss handlers to
* copy the value of the general register specified in r8 into
* a -1 in it, but that is OK, it just means that we will have
* to use the slow path instead).
*/
-
-get_register:
blr %r8,%r0
nop
bv %r0(%r25) /* r0 */
bv %r0(%r25) /* r31 */
copy %r31,%r1
+
+set_register:
/*
* set_register is used by the non access tlb miss handlers to
* copy the value of r1 into the general register specified in
* r8.
*/
-
-set_register:
blr %r8,%r0
nop
bv %r0(%r25) /* r0 (silly, but it is a place holder) */
copy %r1,%r30
bv %r0(%r25) /* r31 */
copy %r1,%r31
+