#include <asm/asm-offsets.h>
#include <asm/unistd.h>
#include <asm/errno.h>
#include <asm/page.h>
#include <asm/psw.h>
#include <asm/thread_info.h>
#include <asm/assembly.h>
#include <asm/processor.h>
#include <asm/cache.h>
#include <asm/spinlock_types.h>
#include <linux/linkage.h>
#define KILL_INSN break 0,0
.level PA_ASM_LEVEL
.macro lws_pagefault_disable reg1,reg2
mfctl %cr30, \reg2
ldo TASK_PAGEFAULT_DISABLED(\reg2), \reg2
ldw 0(%sr2,\reg2), \reg1
ldo 1(\reg1), \reg1
stw \reg1, 0(%sr2,\reg2)
.endm
.macro lws_pagefault_enable reg1,reg2
mfctl %cr30, \reg2
ldo TASK_PAGEFAULT_DISABLED(\reg2), \reg2
ldw 0(%sr2,\reg2), \reg1
ldo -1(\reg1), \reg1
stw \reg1, 0(%sr2,\reg2)
.endm
.macro spinlock_check spin_val,tmpreg
#ifdef CONFIG_LIGHTWEIGHT_SPINLOCK_CHECK
ldi __ARCH_SPIN_LOCK_UNLOCKED_VAL, \tmpreg
andcm,= \spin_val, \tmpreg, %r0
.word SPINLOCK_BREAK_INSN
#endif
.endm
.text
.import syscall_exit,code
.import syscall_exit_rfi,code
.align PAGE_SIZE
ENTRY(linux_gateway_page)
.rept 44
KILL_INSN
.endr
#define __NR_lws_entries (5)
lws_entry:
gate lws_start, %r0
depi PRIV_USER, 31, 2, %r31
.rept 10
KILL_INSN
.endr
set_thread_pointer:
gate .+8, %r0
depi PRIV_USER, 31, 2, %r31
be 0(%sr7,%r31)
mtctl %r26, %cr27
.rept 4
KILL_INSN
.endr
.align LINUX_GATEWAY_ADDR
linux_gateway_entry:
gate .+8, %r0
mtsp %r0,%sr4
mtsp %r0,%sr5
mtsp %r0,%sr6
#ifdef CONFIG_64BIT
ssm PSW_SM_W, %r1
extrd,u %r1,PSW_W_BIT,1,%r1
or,ev %r1,%r30,%r30
b,n 1f
depdi 0, 31, 32, %r26
depdi 0, 31, 32, %r25
depdi 0, 31, 32, %r24
depdi 0, 31, 32, %r23
depdi 0, 31, 32, %r22
depdi 0, 31, 32, %r21
1:
#endif
mfsp %sr7,%r1
rsm PSW_SM_I, %r0
mtsp %r1,%sr3
mfctl %cr30,%r1
xor %r1,%r30,%r30
xor %r1,%r30,%r1
xor %r1,%r30,%r30
LDREG TASK_STACK(%r30),%r30
ldo FRAME_SIZE(%r30),%r30
mtsp %r0,%sr7
ssm PSW_SM_I, %r0
STREGM %r1,FRAME_SIZE(%r30)
mfctl %cr30,%r1
STREG %r0, TASK_PT_PSW(%r1)
STREG %r2, TASK_PT_GR2(%r1)
STREG %r19, TASK_PT_GR19(%r1)
LDREGM -FRAME_SIZE(%r30), %r2
#ifdef CONFIG_64BIT
extrd,u %r2,63,1,%r19
#if 0
xor %r19,%r2,%r2
depd,z %r19,1,1,%r19
std %r19,TASK_PT_PSW(%r1)
#endif
#endif
STREG %r2, TASK_PT_GR30(%r1)
STREG %r20, TASK_PT_GR20(%r1)
STREG %r21, TASK_PT_GR21(%r1)
STREG %r22, TASK_PT_GR22(%r1)
STREG %r23, TASK_PT_GR23(%r1)
STREG %r24, TASK_PT_GR24(%r1)
STREG %r25, TASK_PT_GR25(%r1)
STREG %r26, TASK_PT_GR26(%r1)
STREG %r27, TASK_PT_GR27(%r1)
STREG %r28, TASK_PT_GR28(%r1)
STREG %r0, TASK_PT_ORIG_R28(%r1)
STREG %r29, TASK_PT_GR29(%r1)
STREG %r31, TASK_PT_GR31(%r1)
ldo TASK_PT_FR0(%r1), %r27
save_fp %r27
mfctl %cr11, %r27
STREG %r27, TASK_PT_SAR(%r1)
loadgp
#ifdef CONFIG_64BIT
ldo -16(%r30),%r29
copy %r19,%r2
#else
stw %r22, -52(%r30)
stw %r21, -56(%r30)
#endif
mfctl %cr30, %r1
LDREG TASK_TI_FLAGS(%r1),%r1
ldi _TIF_SYSCALL_TRACE_MASK, %r19
and,COND(=) %r1, %r19, %r0
b,n .Ltracesys
#ifdef CONFIG_64BIT
ldil L%sys_call_table, %r1
or,ev %r2,%r2,%r2
ldil L%sys_call_table64, %r1
ldo R%sys_call_table(%r1), %r19
or,ev %r2,%r2,%r2
ldo R%sys_call_table64(%r1), %r19
#else
load32 sys_call_table, %r19
#endif
comiclr,>> __NR_Linux_syscalls, %r20, %r0
b,n .Lsyscall_nosys
LDREGX %r20(%r19), %r19
ldi __NR_rt_sigreturn,%r2
comb,= %r2,%r20,.Lrt_sigreturn
.Lin_syscall:
ldil L%syscall_exit,%r2
be 0(%sr7,%r19)
ldo R%syscall_exit(%r2),%r2
.Lrt_sigreturn:
comib,<> 0,%r25,.Lin_syscall
ldil L%syscall_exit_rfi,%r2
be 0(%sr7,%r19)
ldo R%syscall_exit_rfi(%r2),%r2
.Lsyscall_nosys:
syscall_nosys:
ldil L%syscall_exit,%r1
be R%syscall_exit(%sr7,%r1)
ldo -ENOSYS(%r0),%r28
.Ltracesys:
tracesys:
mfctl %cr30,%r1
ssm 0,%r2
STREG %r2,TASK_PT_PSW(%r1)
mfsp %sr0,%r2
STREG %r2,TASK_PT_SR0(%r1)
mfsp %sr1,%r2
STREG %r2,TASK_PT_SR1(%r1)
mfsp %sr2,%r2
STREG %r2,TASK_PT_SR2(%r1)
mfsp %sr3,%r2
STREG %r2,TASK_PT_SR3(%r1)
STREG %r2,TASK_PT_SR4(%r1)
STREG %r2,TASK_PT_SR5(%r1)
STREG %r2,TASK_PT_SR6(%r1)
STREG %r2,TASK_PT_SR7(%r1)
STREG %r2,TASK_PT_IASQ0(%r1)
STREG %r2,TASK_PT_IASQ1(%r1)
LDREG TASK_PT_GR31(%r1),%r2
STREG %r2,TASK_PT_IAOQ0(%r1)
ldo 4(%r2),%r2
STREG %r2,TASK_PT_IAOQ1(%r1)
ldo TASK_REGS(%r1),%r2
STREG %r3,PT_GR3(%r2)
STREG %r4,PT_GR4(%r2)
STREG %r5,PT_GR5(%r2)
STREG %r6,PT_GR6(%r2)
STREG %r7,PT_GR7(%r2)
STREG %r8,PT_GR8(%r2)
STREG %r9,PT_GR9(%r2)
STREG %r10,PT_GR10(%r2)
STREG %r11,PT_GR11(%r2)
STREG %r12,PT_GR12(%r2)
STREG %r13,PT_GR13(%r2)
STREG %r14,PT_GR14(%r2)
STREG %r15,PT_GR15(%r2)
STREG %r16,PT_GR16(%r2)
STREG %r17,PT_GR17(%r2)
STREG %r18,PT_GR18(%r2)
copy %r2,%r26
ldil L%do_syscall_trace_enter,%r1
ldil L%tracesys_next,%r2
be R%do_syscall_trace_enter(%sr7,%r1)
ldo R%tracesys_next(%r2),%r2
tracesys_next:
copy %ret0,%r20
mfctl %cr30,%r1
LDREG TASK_PT_GR28(%r1), %r28
LDREG TASK_PT_GR26(%r1), %r26
LDREG TASK_PT_GR25(%r1), %r25
LDREG TASK_PT_GR24(%r1), %r24
LDREG TASK_PT_GR23(%r1), %r23
LDREG TASK_PT_GR22(%r1), %r22
LDREG TASK_PT_GR21(%r1), %r21
#ifdef CONFIG_64BIT
ldo -16(%r30),%r29
#else
stw %r22, -52(%r30)
stw %r21, -56(%r30)
#endif
cmpib,COND(=),n -1,%r20,tracesys_exit
comiclr,>> __NR_Linux_syscalls, %r20, %r0
b,n .Ltracesys_nosys
#ifdef CONFIG_64BIT
LDREG TASK_PT_GR30(%r1), %r19
extrd,u %r19,63,1,%r2
ldil L%sys_call_table, %r1
or,ev %r2,%r2,%r2
ldil L%sys_call_table64, %r1
ldo R%sys_call_table(%r1), %r19
or,ev %r2,%r2,%r2
ldo R%sys_call_table64(%r1), %r19
#else
load32 sys_call_table, %r19
#endif
LDREGX %r20(%r19), %r19
ldi __NR_rt_sigreturn,%r2
comb,= %r2,%r20,.Ltrace_rt_sigreturn
.Ltrace_in_syscall:
ldil L%tracesys_exit,%r2
be 0(%sr7,%r19)
ldo R%tracesys_exit(%r2),%r2
.Ltracesys_nosys:
ldo -ENOSYS(%r0),%r28
tracesys_exit:
mfctl %cr30,%r1
#ifdef CONFIG_64BIT
ldo -16(%r30),%r29
#endif
ldo TASK_REGS(%r1),%r26
BL do_syscall_trace_exit,%r2
STREG %r28,TASK_PT_GR28(%r1)
mfctl %cr30,%r1
LDREG TASK_PT_GR28(%r1), %r28
ldil L%syscall_exit,%r1
be,n R%syscall_exit(%sr7,%r1)
.Ltrace_rt_sigreturn:
comib,<> 0,%r25,.Ltrace_in_syscall
ldil L%tracesys_sigexit,%r2
be 0(%sr7,%r19)
ldo R%tracesys_sigexit(%r2),%r2
tracesys_sigexit:
mfctl %cr30,%r1
#ifdef CONFIG_64BIT
ldo -16(%r30),%r29
#endif
BL do_syscall_trace_exit,%r2
ldo TASK_REGS(%r1),%r26
ldil L%syscall_exit_rfi,%r1
be,n R%syscall_exit_rfi(%sr7,%r1)
lws_start:
#ifdef CONFIG_64BIT
ssm PSW_SM_W, %r1
extrd,u %r1,PSW_W_BIT,1,%r1
or,od %r1,%r30,%r30
depdi 0, 31, 32, %r20
#endif
comiclr,>> __NR_lws_entries, %r20, %r0
b,n lws_exit_nosys
ldil L%lws_table, %r1
ldo R%lws_table(%r1), %r28
LDREGX %r20(%sr2,r28), %r21
be,n 0(%sr2,%r21)
lws_exit_noerror:
lws_pagefault_enable %r1,%r21
ldi __ARCH_SPIN_LOCK_UNLOCKED_VAL, %r21
stw,ma %r21, 0(%sr2,%r20)
ssm PSW_SM_I, %r0
b lws_exit
copy %r0, %r21
lws_wouldblock:
ssm PSW_SM_I, %r0
ldo 2(%r0), %r28
b lws_exit
ldo -EAGAIN(%r0), %r21
lws_pagefault:
lws_pagefault_enable %r1,%r21
ldi __ARCH_SPIN_LOCK_UNLOCKED_VAL, %r21
stw,ma %r21, 0(%sr2,%r20)
ssm PSW_SM_I, %r0
ldo 3(%r0),%r28
b lws_exit
ldo -EAGAIN(%r0),%r21
lws_fault:
ldo 1(%r0),%r28
b lws_exit
ldo -EFAULT(%r0),%r21
lws_exit_nosys:
ldo -ENOSYS(%r0),%r21
lws_exit:
#ifdef CONFIG_64BIT
extrd,u,*<> %r30,63,1,%r1
rsm PSW_SM_W, %r0
xor %r30,%r1,%r30
#endif
be,n 0(%sr7, %r31)
lws_compare_and_swap64:
#ifdef CONFIG_64BIT
b,n lws_compare_and_swap
#else
b,n lws_exit_nosys
#endif
lws_compare_and_swap32:
#ifdef CONFIG_64BIT
bb,<,n %sp, 31, lws_compare_and_swap
depdi 0, 31, 32, %r26
depdi 0, 31, 32, %r25
depdi 0, 31, 32, %r24
#endif
lws_compare_and_swap:
1: ldw 0(%r26), %r28
proberi (%r26), PRIV_USER, %r28
comb,=,n %r28, %r0, lws_fault
nop
2: stbys,e %r0, 0(%r26)
extru_safe %r26, 27, 8, %r20
ldil L%lws_lock_start, %r28
ldo R%lws_lock_start(%r28), %r28
shlw %r20, 4, %r20
add %r20, %r28, %r20
rsm PSW_SM_I, %r0
LDCW 0(%sr2,%r20), %r28
spinlock_check %r28, %r21
comclr,<> %r0, %r28, %r0
b,n lws_wouldblock
lws_pagefault_disable %r21,%r28
3: ldw 0(%r26), %r28
sub,<> %r28, %r25, %r0
4: stw %r24, 0(%r26)
b,n lws_exit_noerror
5: b,n lws_fault
ASM_EXCEPTIONTABLE_ENTRY(1b-linux_gateway_page, 5b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(2b-linux_gateway_page, 5b-linux_gateway_page)
6: b,n lws_pagefault
ASM_EXCEPTIONTABLE_ENTRY(3b-linux_gateway_page, 6b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(4b-linux_gateway_page, 6b-linux_gateway_page)
lws_compare_and_swap_2:
#ifdef CONFIG_64BIT
bb,<,n %sp, 31, cas2_begin
depdi 0, 31, 32, %r26
depdi 0, 31, 32, %r25
depdi 0, 31, 32, %r24
#endif
cas2_begin:
subi,>>= 3, %r23, %r0
b,n lws_exit_nosys
shlw %r23, 2, %r29
blr %r29, %r0
nop
1: ldb 0(%r25), %r25
b cas2_lock_start
2: ldb 0(%r24), %r24
nop
nop
nop
nop
nop
3: ldh 0(%r25), %r25
b cas2_lock_start
4: ldh 0(%r24), %r24
nop
nop
nop
nop
nop
5: ldw 0(%r25), %r25
b cas2_lock_start
6: ldw 0(%r24), %r24
nop
nop
nop
nop
nop
#ifdef CONFIG_64BIT
7: ldd 0(%r25), %r25
8: ldd 0(%r24), %r24
#else
7: ldw 0(%r25), %r22
8: ldw 4(%r25), %r23
9: flddx 0(%r24), %fr4
#endif
cas2_lock_start:
copy %r26, %r28
depi_safe 0, 31, 2, %r28
10: ldw 0(%r28), %r1
proberi (%r28), PRIV_USER, %r1
comb,=,n %r1, %r0, lws_fault
nop
11: stbys,e %r0, 0(%r28)
extru_safe %r26, 27, 8, %r20
ldil L%lws_lock_start, %r28
ldo R%lws_lock_start(%r28), %r28
shlw %r20, 4, %r20
add %r20, %r28, %r20
rsm PSW_SM_I, %r0
LDCW 0(%sr2,%r20), %r28
spinlock_check %r28, %r21
comclr,<> %r0, %r28, %r0
b,n lws_wouldblock
lws_pagefault_disable %r21,%r28
blr %r29, %r0
ldo 1(%r0),%r28
12: ldb 0(%r26), %r29
sub,= %r29, %r25, %r0
b,n lws_exit_noerror
13: stb %r24, 0(%r26)
b lws_exit_noerror
copy %r0, %r28
nop
nop
14: ldh 0(%r26), %r29
sub,= %r29, %r25, %r0
b,n lws_exit_noerror
15: sth %r24, 0(%r26)
b lws_exit_noerror
copy %r0, %r28
nop
nop
16: ldw 0(%r26), %r29
sub,= %r29, %r25, %r0
b,n lws_exit_noerror
17: stw %r24, 0(%r26)
b lws_exit_noerror
copy %r0, %r28
nop
nop
#ifdef CONFIG_64BIT
18: ldd 0(%r26), %r29
sub,*= %r29, %r25, %r0
b,n lws_exit_noerror
19: std %r24, 0(%r26)
copy %r0, %r28
#else
18: ldw 0(%r26), %r29
sub,= %r29, %r22, %r0
b,n lws_exit_noerror
19: ldw 4(%r26), %r29
sub,= %r29, %r23, %r0
b,n lws_exit_noerror
20: fstdx %fr4, 0(%r26)
copy %r0, %r28
#endif
b lws_exit_noerror
copy %r0, %r28
30: b,n lws_fault
ASM_EXCEPTIONTABLE_ENTRY(1b-linux_gateway_page, 30b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(2b-linux_gateway_page, 30b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(3b-linux_gateway_page, 30b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(4b-linux_gateway_page, 30b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(5b-linux_gateway_page, 30b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(6b-linux_gateway_page, 30b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(7b-linux_gateway_page, 30b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(8b-linux_gateway_page, 30b-linux_gateway_page)
#ifndef CONFIG_64BIT
ASM_EXCEPTIONTABLE_ENTRY(9b-linux_gateway_page, 30b-linux_gateway_page)
#endif
ASM_EXCEPTIONTABLE_ENTRY(10b-linux_gateway_page, 30b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(11b-linux_gateway_page, 30b-linux_gateway_page)
31: b,n lws_pagefault
ASM_EXCEPTIONTABLE_ENTRY(12b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(13b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(14b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(15b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(16b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(17b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(18b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(19b-linux_gateway_page, 31b-linux_gateway_page)
#ifndef CONFIG_64BIT
ASM_EXCEPTIONTABLE_ENTRY(20b-linux_gateway_page, 31b-linux_gateway_page)
#endif
lws_atomic_xchg:
#ifdef CONFIG_64BIT
bb,<,n %sp, 31, atomic_xchg_begin
depdi 0, 31, 32, %r26
depdi 0, 31, 32, %r25
depdi 0, 31, 32, %r24
depdi 0, 31, 32, %r23
#endif
atomic_xchg_begin:
subi,>>= 3, %r25, %r0
b,n lws_exit_nosys
shlw %r25, 2, %r1
blr %r1, %r0
nop
1: ldb 0(%r24), %r20
proberi (%r24), PRIV_USER, %r20
comb,=,n %r20, %r0, lws_fault
nop
copy %r23, %r20
depi_safe 0, 31, 2, %r20
b atomic_xchg_start
2: stbys,e %r0, 0(%r20)
3: ldh 0(%r24), %r20
proberi (%r24), PRIV_USER, %r20
comb,=,n %r20, %r0, lws_fault
nop
copy %r23, %r20
depi_safe 0, 31, 2, %r20
b atomic_xchg_start
4: stbys,e %r0, 0(%r20)
5: ldw 0(%r24), %r20
proberi (%r24), PRIV_USER, %r20
comb,=,n %r20, %r0, lws_fault
nop
b atomic_xchg_start
6: stbys,e %r0, 0(%r23)
nop
nop
#ifdef CONFIG_64BIT
7: ldd 0(%r24), %r20
proberi (%r24), PRIV_USER, %r20
comb,=,n %r20, %r0, lws_fault
nop
8: stdby,e %r0, 0(%r23)
#else
7: ldw 0(%r24), %r20
8: ldw 4(%r24), %r20
proberi (%r24), PRIV_USER, %r20
comb,=,n %r20, %r0, lws_fault
nop
copy %r23, %r20
depi_safe 0, 31, 2, %r20
9: stbys,e %r0, 0(%r20)
10: stbys,e %r0, 4(%r20)
#endif
atomic_xchg_start:
copy %r26, %r28
depi_safe 0, 31, 2, %r28
11: ldw 0(%r28), %r1
12: stbys,e %r0, 0(%r28)
extru_safe %r26, 27, 8, %r20
ldil L%lws_lock_start, %r28
ldo R%lws_lock_start(%r28), %r28
shlw %r20, 4, %r20
add %r20, %r28, %r20
rsm PSW_SM_I, %r0
LDCW 0(%sr2,%r20), %r28
spinlock_check %r28, %r21
comclr,<> %r0, %r28, %r0
b,n lws_wouldblock
lws_pagefault_disable %r21,%r28
blr %r1, %r0
ldo 1(%r0),%r28
14: ldb 0(%r26), %r1
15: stb %r1, 0(%r23)
15: ldb 0(%r24), %r1
17: stb %r1, 0(%r26)
b lws_exit_noerror
copy %r0, %r28
nop
nop
18: ldh 0(%r26), %r1
19: sth %r1, 0(%r23)
20: ldh 0(%r24), %r1
21: sth %r1, 0(%r26)
b lws_exit_noerror
copy %r0, %r28
nop
nop
22: ldw 0(%r26), %r1
23: stw %r1, 0(%r23)
24: ldw 0(%r24), %r1
25: stw %r1, 0(%r26)
b lws_exit_noerror
copy %r0, %r28
nop
nop
#ifdef CONFIG_64BIT
26: ldd 0(%r26), %r1
27: std %r1, 0(%r23)
28: ldd 0(%r24), %r1
29: std %r1, 0(%r26)
#else
26: flddx 0(%r26), %fr4
27: fstdx %fr4, 0(%r23)
28: flddx 0(%r24), %fr4
29: fstdx %fr4, 0(%r26)
#endif
b lws_exit_noerror
copy %r0, %r28
30: b,n lws_fault
ASM_EXCEPTIONTABLE_ENTRY(1b-linux_gateway_page, 30b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(2b-linux_gateway_page, 30b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(3b-linux_gateway_page, 30b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(4b-linux_gateway_page, 30b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(5b-linux_gateway_page, 30b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(6b-linux_gateway_page, 30b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(7b-linux_gateway_page, 30b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(8b-linux_gateway_page, 30b-linux_gateway_page)
#ifndef CONFIG_64BIT
ASM_EXCEPTIONTABLE_ENTRY(9b-linux_gateway_page, 30b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(10b-linux_gateway_page, 30b-linux_gateway_page)
#endif
ASM_EXCEPTIONTABLE_ENTRY(11b-linux_gateway_page, 30b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(12b-linux_gateway_page, 30b-linux_gateway_page)
31: b,n lws_pagefault
ASM_EXCEPTIONTABLE_ENTRY(14b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(15b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(16b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(17b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(18b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(19b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(20b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(21b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(22b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(23b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(24b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(25b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(26b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(27b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(28b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(29b-linux_gateway_page, 31b-linux_gateway_page)
lws_atomic_store:
#ifdef CONFIG_64BIT
bb,<,n %sp, 31, atomic_store_begin
depdi 0, 31, 32, %r26
depdi 0, 31, 32, %r25
depdi 0, 31, 32, %r24
#endif
atomic_store_begin:
subi,>>= 3, %r25, %r0
b,n lws_exit_nosys
shlw %r25, 1, %r1
blr %r1, %r0
nop
1: ldb 0(%r24), %r20
b,n atomic_store_start
nop
nop
2: ldh 0(%r24), %r20
b,n atomic_store_start
nop
nop
3: ldw 0(%r24), %r20
b,n atomic_store_start
nop
nop
#ifdef CONFIG_64BIT
4: ldd 0(%r24), %r20
#else
4: ldw 0(%r24), %r20
5: ldw 4(%r24), %r20
#endif
atomic_store_start:
copy %r26, %r28
depi_safe 0, 31, 2, %r28
6: ldw 0(%r28), %r1
7: stbys,e %r0, 0(%r28)
extru_safe %r26, 27, 8, %r20
ldil L%lws_lock_start, %r28
ldo R%lws_lock_start(%r28), %r28
shlw %r20, 4, %r20
add %r20, %r28, %r20
rsm PSW_SM_I, %r0
LDCW 0(%sr2,%r20), %r28
spinlock_check %r28, %r21
comclr,<> %r0, %r28, %r0
b,n lws_wouldblock
lws_pagefault_disable %r21,%r28
blr %r1, %r0
ldo 1(%r0),%r28
9: ldb 0(%r24), %r1
10: stb %r1, 0(%r26)
b lws_exit_noerror
copy %r0, %r28
11: ldh 0(%r24), %r1
12: sth %r1, 0(%r26)
b lws_exit_noerror
copy %r0, %r28
13: ldw 0(%r24), %r1
14: stw %r1, 0(%r26)
b lws_exit_noerror
copy %r0, %r28
#ifdef CONFIG_64BIT
15: ldd 0(%r24), %r1
16: std %r1, 0(%r26)
#else
15: flddx 0(%r24), %fr4
16: fstdx %fr4, 0(%r26)
#endif
b lws_exit_noerror
copy %r0, %r28
30: b,n lws_fault
ASM_EXCEPTIONTABLE_ENTRY(1b-linux_gateway_page, 30b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(2b-linux_gateway_page, 30b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(3b-linux_gateway_page, 30b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(4b-linux_gateway_page, 30b-linux_gateway_page)
#ifndef CONFIG_64BIT
ASM_EXCEPTIONTABLE_ENTRY(5b-linux_gateway_page, 30b-linux_gateway_page)
#endif
ASM_EXCEPTIONTABLE_ENTRY(6b-linux_gateway_page, 30b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(7b-linux_gateway_page, 30b-linux_gateway_page)
31: b,n lws_pagefault
ASM_EXCEPTIONTABLE_ENTRY(9b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(10b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(11b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(12b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(13b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(14b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(15b-linux_gateway_page, 31b-linux_gateway_page)
ASM_EXCEPTIONTABLE_ENTRY(16b-linux_gateway_page, 31b-linux_gateway_page)
.align PAGE_SIZE
END(linux_gateway_page)
ENTRY(end_linux_gateway_page)
#define LWS_ENTRY(_name_) ASM_ULONG_INSN (lws_##_name_ - linux_gateway_page)
.section .rodata,"a"
.align 8
ENTRY(lws_table)
LWS_ENTRY(compare_and_swap32)
LWS_ENTRY(compare_and_swap64)
LWS_ENTRY(compare_and_swap_2)
LWS_ENTRY(atomic_xchg)
LWS_ENTRY(atomic_store)
END(lws_table)
#ifdef CONFIG_64BIT
#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, compat)
#else
#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native)
#endif
#define __SYSCALL(nr, entry) ASM_ULONG_INSN entry
.align 8
ENTRY(sys_call_table)
.export sys_call_table,data
#include <asm/syscall_table_32.h>
END(sys_call_table)
#ifdef CONFIG_64BIT
#undef __SYSCALL_WITH_COMPAT
#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native)
.align 8
ENTRY(sys_call_table64)
#include <asm/syscall_table_64.h>
END(sys_call_table64)
#endif
.section .data
.align L1_CACHE_BYTES
ENTRY(lws_lock_start)
.rept 256
.word __ARCH_SPIN_LOCK_UNLOCKED_VAL
.word 0
.word 0
.word 0
.endr
END(lws_lock_start)
.previous
.end