1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33#include <asm/asm-offsets.h>
34#include <asm/unistd.h>
35#include <asm/errno.h>
36#include <asm/page.h>
37#include <asm/psw.h>
38#include <asm/thread_info.h>
39#include <asm/assembly.h>
40#include <asm/processor.h>
41#include <asm/cache.h>
42
43#include <linux/linkage.h>
44
45
46
47
48
49#define KILL_INSN break 0,0
50
51 .level LEVEL
52
53 .text
54
55 .import syscall_exit,code
56 .import syscall_exit_rfi,code
57
58
59
60
61
62
63
64
65
66 .align PAGE_SIZE
67ENTRY(linux_gateway_page)
68
69
70 .rept 44
71 KILL_INSN
72 .endr
73
74
75
76
77#define __NR_lws_entries (3)
78
79lws_entry:
80 gate lws_start, %r0
81 depi 3, 31, 2, %r31
82
83
84 .rept 10
85 KILL_INSN
86 .endr
87
88
89
90set_thread_pointer:
91 gate .+8, %r0
92 depi 3, 31, 2, %r31
93 be 0(%sr7,%r31)
94 mtctl %r26, %cr27
95
96
97
98 .rept 4
99 KILL_INSN
100 .endr
101
102
103 .align LINUX_GATEWAY_ADDR
104linux_gateway_entry:
105 gate .+8, %r0
106 mtsp %r0,%sr4
107 mtsp %r0,%sr5
108 mtsp %r0,%sr6
109
110#ifdef CONFIG_64BIT
111
112
113
114
115
116
117 ssm PSW_SM_W, %r1
118 extrd,u %r1,PSW_W_BIT,1,%r1
119
120
121 or,ev %r1,%r30,%r30
122 b,n 1f
123
124
125
126 depdi 0, 31, 32, %r26
127 depdi 0, 31, 32, %r25
128 depdi 0, 31, 32, %r24
129 depdi 0, 31, 32, %r23
130 depdi 0, 31, 32, %r22
131 depdi 0, 31, 32, %r21
1321:
133#endif
134
135
136
137
138 mfsp %sr7,%r1
139 rsm PSW_SM_I, %r0
140 mtsp %r1,%sr3
141
142 mfctl %cr30,%r1
143 xor %r1,%r30,%r30
144 xor %r1,%r30,%r1
145 xor %r1,%r30,%r30
146
147 ldo THREAD_SZ_ALGN+FRAME_SIZE(%r30),%r30
148
149
150
151
152
153
154
155 mtsp %r0,%sr7
156 ssm PSW_SM_I, %r0
157 STREGM %r1,FRAME_SIZE(%r30)
158 mfctl %cr30,%r1
159 LDREG TI_TASK(%r1),%r1
160
161
162
163
164
165
166 STREG %r0, TASK_PT_PSW(%r1)
167 STREG %r2, TASK_PT_GR2(%r1)
168 STREG %r19, TASK_PT_GR19(%r1)
169
170 LDREGM -FRAME_SIZE(%r30), %r2
171#ifdef CONFIG_64BIT
172 extrd,u %r2,63,1,%r19
173
174 xor %r19,%r2,%r2
175 depd,z %r19,1,1,%r19
176 std %r19,TASK_PT_PSW(%r1)
177#endif
178#endif
179 STREG %r2, TASK_PT_GR30(%r1)
180
181 STREG %r20, TASK_PT_GR20(%r1)
182 STREG %r21, TASK_PT_GR21(%r1)
183 STREG %r22, TASK_PT_GR22(%r1)
184 STREG %r23, TASK_PT_GR23(%r1)
185 STREG %r24, TASK_PT_GR24(%r1)
186 STREG %r25, TASK_PT_GR25(%r1)
187 STREG %r26, TASK_PT_GR26(%r1)
188 STREG %r27, TASK_PT_GR27(%r1)
189 STREG %r28, TASK_PT_GR28(%r1)
190 STREG %r0, TASK_PT_ORIG_R28(%r1)
191 STREG %r29, TASK_PT_GR29(%r1)
192 STREG %r31, TASK_PT_GR31(%r1)
193
194 ldo TASK_PT_FR0(%r1), %r27
195 save_fp %r27
196
197 mfctl %cr11, %r27
198 STREG %r27, TASK_PT_SAR(%r1)
199
200 loadgp
201
202#ifdef CONFIG_64BIT
203 ldo -16(%r30),%r29
204 copy %r19,%r2
205#else
206
207
208 stw %r22, -52(%r30)
209 stw %r21, -56(%r30)
210#endif
211
212
213 mfctl %cr30, %r1
214 LDREG TI_FLAGS(%r1),%r1
215 ldi _TIF_SYSCALL_TRACE_MASK, %r19
216 and,COND(=) %r1, %r19, %r0
217 b,n .Ltracesys
218
219
220
221
222#ifdef CONFIG_64BIT
223 ldil L%sys_call_table, %r1
224 or,= %r2,%r2,%r2
225 addil L%(sys_call_table64-sys_call_table), %r1
226 ldo R%sys_call_table(%r1), %r19
227 or,= %r2,%r2,%r2
228 ldo R%sys_call_table64(%r1), %r19
229#else
230 ldil L%sys_call_table, %r1
231 ldo R%sys_call_table(%r1), %r19
232#endif
233 comiclr,>> __NR_Linux_syscalls, %r20, %r0
234 b,n .Lsyscall_nosys
235
236 LDREGX %r20(%r19), %r19
237
238
239
240
241
242
243 ldi __NR_rt_sigreturn,%r2
244 comb,= %r2,%r20,.Lrt_sigreturn
245.Lin_syscall:
246 ldil L%syscall_exit,%r2
247 be 0(%sr7,%r19)
248 ldo R%syscall_exit(%r2),%r2
249.Lrt_sigreturn:
250 comib,<> 0,%r25,.Lin_syscall
251 ldil L%syscall_exit_rfi,%r2
252 be 0(%sr7,%r19)
253 ldo R%syscall_exit_rfi(%r2),%r2
254
255
256
257
258
259
260.Lsyscall_nosys:
261syscall_nosys:
262 ldil L%syscall_exit,%r1
263 be R%syscall_exit(%sr7,%r1)
264 ldo -ENOSYS(%r0),%r28
265
266
267
268
269.Ltracesys:
270tracesys:
271
272
273
274
275
276
277
278
279
280 ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
281 LDREG TI_TASK(%r1), %r1
282 ssm 0,%r2
283 STREG %r2,TASK_PT_PSW(%r1)
284 mfsp %sr0,%r2
285 STREG %r2,TASK_PT_SR0(%r1)
286 mfsp %sr1,%r2
287 STREG %r2,TASK_PT_SR1(%r1)
288 mfsp %sr2,%r2
289 STREG %r2,TASK_PT_SR2(%r1)
290 mfsp %sr3,%r2
291 STREG %r2,TASK_PT_SR3(%r1)
292 STREG %r2,TASK_PT_SR4(%r1)
293 STREG %r2,TASK_PT_SR5(%r1)
294 STREG %r2,TASK_PT_SR6(%r1)
295 STREG %r2,TASK_PT_SR7(%r1)
296 STREG %r2,TASK_PT_IASQ0(%r1)
297 STREG %r2,TASK_PT_IASQ1(%r1)
298 LDREG TASK_PT_GR31(%r1),%r2
299 STREG %r2,TASK_PT_IAOQ0(%r1)
300 ldo 4(%r2),%r2
301 STREG %r2,TASK_PT_IAOQ1(%r1)
302 ldo TASK_REGS(%r1),%r2
303
304 STREG %r3,PT_GR3(%r2)
305 STREG %r4,PT_GR4(%r2)
306 STREG %r5,PT_GR5(%r2)
307 STREG %r6,PT_GR6(%r2)
308 STREG %r7,PT_GR7(%r2)
309 STREG %r8,PT_GR8(%r2)
310 STREG %r9,PT_GR9(%r2)
311 STREG %r10,PT_GR10(%r2)
312 STREG %r11,PT_GR11(%r2)
313 STREG %r12,PT_GR12(%r2)
314 STREG %r13,PT_GR13(%r2)
315 STREG %r14,PT_GR14(%r2)
316 STREG %r15,PT_GR15(%r2)
317 STREG %r16,PT_GR16(%r2)
318 STREG %r17,PT_GR17(%r2)
319 STREG %r18,PT_GR18(%r2)
320
321
322 copy %r2,%r26
323 ldil L%do_syscall_trace_enter,%r1
324 ldil L%tracesys_next,%r2
325 be R%do_syscall_trace_enter(%sr7,%r1)
326 ldo R%tracesys_next(%r2),%r2
327
328tracesys_next:
329
330
331
332
333 copy %ret0,%r20
334 ldil L%sys_call_table,%r1
335 ldo R%sys_call_table(%r1), %r19
336
337 ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
338 LDREG TI_TASK(%r1), %r1
339 LDREG TASK_PT_GR28(%r1), %r28
340 LDREG TASK_PT_GR26(%r1), %r26
341 LDREG TASK_PT_GR25(%r1), %r25
342 LDREG TASK_PT_GR24(%r1), %r24
343 LDREG TASK_PT_GR23(%r1), %r23
344 LDREG TASK_PT_GR22(%r1), %r22
345 LDREG TASK_PT_GR21(%r1), %r21
346#ifdef CONFIG_64BIT
347 ldo -16(%r30),%r29
348#else
349 stw %r22, -52(%r30)
350 stw %r21, -56(%r30)
351#endif
352
353 cmpib,COND(=),n -1,%r20,tracesys_exit
354 comiclr,>> __NR_Linux_syscalls, %r20, %r0
355 b,n .Ltracesys_nosys
356
357 LDREGX %r20(%r19), %r19
358
359
360
361
362
363
364 ldi __NR_rt_sigreturn,%r2
365 comb,= %r2,%r20,.Ltrace_rt_sigreturn
366.Ltrace_in_syscall:
367 ldil L%tracesys_exit,%r2
368 be 0(%sr7,%r19)
369 ldo R%tracesys_exit(%r2),%r2
370
371.Ltracesys_nosys:
372 ldo -ENOSYS(%r0),%r28
373
374
375
376
377tracesys_exit:
378 ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
379 LDREG TI_TASK(%r1), %r1
380#ifdef CONFIG_64BIT
381 ldo -16(%r30),%r29
382#endif
383 ldo TASK_REGS(%r1),%r26
384 BL do_syscall_trace_exit,%r2
385 STREG %r28,TASK_PT_GR28(%r1)
386 ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
387 LDREG TI_TASK(%r1), %r1
388 LDREG TASK_PT_GR28(%r1), %r28
389
390 ldil L%syscall_exit,%r1
391 be,n R%syscall_exit(%sr7,%r1)
392
393.Ltrace_rt_sigreturn:
394 comib,<> 0,%r25,.Ltrace_in_syscall
395 ldil L%tracesys_sigexit,%r2
396 be 0(%sr7,%r19)
397 ldo R%tracesys_sigexit(%r2),%r2
398
399tracesys_sigexit:
400 ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
401 LDREG TI_TASK(%r1), %r1
402#ifdef CONFIG_64BIT
403 ldo -16(%r30),%r29
404#endif
405 BL do_syscall_trace_exit,%r2
406 ldo TASK_REGS(%r1),%r26
407
408 ldil L%syscall_exit_rfi,%r1
409 be,n R%syscall_exit_rfi(%sr7,%r1)
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464lws_start:
465
466#ifdef CONFIG_64BIT
467
468
469
470 ssm PSW_SM_W, %r1
471 extrd,u %r1,PSW_W_BIT,1,%r1
472
473
474 or,ev %r1,%r30,%r30
475
476
477 depdi 0, 31, 32, %r20
478#endif
479
480
481 comiclr,>> __NR_lws_entries, %r20, %r0
482 b,n lws_exit_nosys
483
484
485 ldil L%lws_table, %r1
486 ldo R%lws_table(%r1), %r28
487 LDREGX %r20(%sr2,r28), %r21
488
489
490 be,n 0(%sr2,%r21)
491
492lws_exit_nosys:
493 ldo -ENOSYS(%r0),%r21
494
495
496lws_exit:
497#ifdef CONFIG_64BIT
498
499
500
501
502 extrd,u,*<> %r30,63,1,%r1
503 rsm PSW_SM_W, %r0
504
505 xor %r30,%r1,%r30
506#endif
507 be,n 0(%sr7, %r31)
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539#define ENABLE_LWS_DEBUG 0
540
541
542lws_compare_and_swap64:
543#ifdef CONFIG_64BIT
544 b,n lws_compare_and_swap
545#else
546
547
548
549
550 b,n lws_exit_nosys
551#endif
552
553
554lws_compare_and_swap32:
555#ifdef CONFIG_64BIT
556
557 depdi 0, 31, 32, %r26
558 depdi 0, 31, 32, %r25
559 depdi 0, 31, 32, %r24
560#endif
561
562lws_compare_and_swap:
563
564 ldil L%lws_lock_start, %r20
565 ldo R%lws_lock_start(%r20), %r28
566
567
568 extru %r26, 27, 4, %r20
569
570
571
572
573 shlw %r20, 4, %r20
574 add %r20, %r28, %r20
575
576
577
578
579
580
581
582
583
584 ldw 4(%sr2,%r20), %r28
585
586 mfctl %cr27, %r21
587 cmpb,<>,n %r21, %r28, cas_lock
588 b lws_exit
589 ldo -EDEADLOCK(%r0), %r21
590cas_lock:
591 cmpb,=,n %r0, %r28, cas_nocontend
592 ldo 1(%r0), %r28
593 b lws_exit
594 ldo -EAGAIN(%r0), %r21
595cas_nocontend:
596# endif
597
598
599 rsm PSW_SM_I, %r0
600
601 LDCW 0(%sr2,%r20), %r28
602 cmpb,<>,n %r0, %r28, cas_action
603cas_wouldblock:
604 ldo 2(%r0), %r28
605 ssm PSW_SM_I, %r0
606 b lws_exit
607 ldo -EAGAIN(%r0), %r21
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625cas_action:
626
627
628 mfctl %cr27, %r1
629 stw %r1, 4(%sr2,%r20)
630#endif
631
6321: ldw,ma 0(%r26), %r28
633 sub,<> %r28, %r25, %r0
6342: stw,ma %r24, 0(%r26)
635
636 sync
637 stw,ma %r20, 0(%sr2,%r20)
638
639
640 stw %r0, 4(%sr2,%r20)
641#endif
642
643 ssm PSW_SM_I, %r0
644
645 b lws_exit
646 copy %r0, %r21
647
6483:
649
650
651 sync
652 stw %r20, 0(%sr2,%r20)
653
654 stw %r0, 4(%sr2,%r20)
655#endif
656 ssm PSW_SM_I, %r0
657 b lws_exit
658 ldo -EFAULT(%r0),%r21
659 nop
660 nop
661 nop
662 nop
663
664
665
666
667 ASM_EXCEPTIONTABLE_ENTRY(1b-linux_gateway_page, 3b-linux_gateway_page)
668 ASM_EXCEPTIONTABLE_ENTRY(2b-linux_gateway_page, 3b-linux_gateway_page)
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693lws_compare_and_swap_2:
694#ifdef CONFIG_64BIT
695
696
697 depdi 0, 31, 32, %r26
698 depdi 0, 31, 32, %r25
699 depdi 0, 31, 32, %r24
700#endif
701
702
703 subi,>>= 3, %r23, %r0
704 b,n lws_exit_nosys
705
706
707
708 shlw %r23, 2, %r29
709 blr %r29, %r0
710 nop
711
712
7134: ldb 0(%r25), %r25
714 b cas2_lock_start
7155: ldb 0(%r24), %r24
716 nop
717 nop
718 nop
719 nop
720 nop
721
722
7236: ldh 0(%r25), %r25
724 b cas2_lock_start
7257: ldh 0(%r24), %r24
726 nop
727 nop
728 nop
729 nop
730 nop
731
732
7338: ldw 0(%r25), %r25
734 b cas2_lock_start
7359: ldw 0(%r24), %r24
736 nop
737 nop
738 nop
739 nop
740 nop
741
742
743#ifdef CONFIG_64BIT
74410: ldd 0(%r25), %r25
74511: ldd 0(%r24), %r24
746#else
747
74810: ldw 0(%r25), %r22
74911: ldw 4(%r25), %r23
750
75112: flddx 0(%r24), %fr4
752#endif
753
754cas2_lock_start:
755
756 ldil L%lws_lock_start, %r20
757 ldo R%lws_lock_start(%r20), %r28
758
759
760 extru %r26, 27, 4, %r20
761
762
763
764
765 shlw %r20, 4, %r20
766 add %r20, %r28, %r20
767
768 rsm PSW_SM_I, %r0
769
770 LDCW 0(%sr2,%r20), %r28
771 cmpb,<>,n %r0, %r28, cas2_action
772cas2_wouldblock:
773 ldo 2(%r0), %r28
774 ssm PSW_SM_I, %r0
775 b lws_exit
776 ldo -EAGAIN(%r0), %r21
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794cas2_action:
795
796 blr %r29, %r0
797
798 ldo 1(%r0),%r28
799
800
80113: ldb,ma 0(%r26), %r29
802 sub,= %r29, %r25, %r0
803 b,n cas2_end
80414: stb,ma %r24, 0(%r26)
805 b cas2_end
806 copy %r0, %r28
807 nop
808 nop
809
810
81115: ldh,ma 0(%r26), %r29
812 sub,= %r29, %r25, %r0
813 b,n cas2_end
81416: sth,ma %r24, 0(%r26)
815 b cas2_end
816 copy %r0, %r28
817 nop
818 nop
819
820
82117: ldw,ma 0(%r26), %r29
822 sub,= %r29, %r25, %r0
823 b,n cas2_end
82418: stw,ma %r24, 0(%r26)
825 b cas2_end
826 copy %r0, %r28
827 nop
828 nop
829
830
831#ifdef CONFIG_64BIT
83219: ldd,ma 0(%r26), %r29
833 sub,*= %r29, %r25, %r0
834 b,n cas2_end
83520: std,ma %r24, 0(%r26)
836 copy %r0, %r28
837#else
838
83919: ldw 0(%r26), %r29
840 sub,= %r29, %r22, %r0
841 b,n cas2_end
842
84320: ldw 4(%r26), %r29
844 sub,= %r29, %r23, %r0
845 b,n cas2_end
846
84721: fstdx %fr4, 0(%r26)
848 copy %r0, %r28
849#endif
850
851cas2_end:
852
853 sync
854 stw,ma %r20, 0(%sr2,%r20)
855
856 ssm PSW_SM_I, %r0
857
858 b lws_exit
859 copy %r0, %r21
860
86122:
862
863
864 sync
865 stw %r20, 0(%sr2,%r20)
866 ssm PSW_SM_I, %r0
867 ldo 1(%r0),%r28
868 b lws_exit
869 ldo -EFAULT(%r0),%r21
870 nop
871 nop
872 nop
873
874
875
876 ASM_EXCEPTIONTABLE_ENTRY(4b-linux_gateway_page, 22b-linux_gateway_page)
877 ASM_EXCEPTIONTABLE_ENTRY(5b-linux_gateway_page, 22b-linux_gateway_page)
878 ASM_EXCEPTIONTABLE_ENTRY(6b-linux_gateway_page, 22b-linux_gateway_page)
879 ASM_EXCEPTIONTABLE_ENTRY(7b-linux_gateway_page, 22b-linux_gateway_page)
880 ASM_EXCEPTIONTABLE_ENTRY(8b-linux_gateway_page, 22b-linux_gateway_page)
881 ASM_EXCEPTIONTABLE_ENTRY(9b-linux_gateway_page, 22b-linux_gateway_page)
882 ASM_EXCEPTIONTABLE_ENTRY(10b-linux_gateway_page, 22b-linux_gateway_page)
883 ASM_EXCEPTIONTABLE_ENTRY(11b-linux_gateway_page, 22b-linux_gateway_page)
884 ASM_EXCEPTIONTABLE_ENTRY(13b-linux_gateway_page, 22b-linux_gateway_page)
885 ASM_EXCEPTIONTABLE_ENTRY(14b-linux_gateway_page, 22b-linux_gateway_page)
886 ASM_EXCEPTIONTABLE_ENTRY(15b-linux_gateway_page, 22b-linux_gateway_page)
887 ASM_EXCEPTIONTABLE_ENTRY(16b-linux_gateway_page, 22b-linux_gateway_page)
888 ASM_EXCEPTIONTABLE_ENTRY(17b-linux_gateway_page, 22b-linux_gateway_page)
889 ASM_EXCEPTIONTABLE_ENTRY(18b-linux_gateway_page, 22b-linux_gateway_page)
890 ASM_EXCEPTIONTABLE_ENTRY(19b-linux_gateway_page, 22b-linux_gateway_page)
891 ASM_EXCEPTIONTABLE_ENTRY(20b-linux_gateway_page, 22b-linux_gateway_page)
892#ifndef CONFIG_64BIT
893 ASM_EXCEPTIONTABLE_ENTRY(12b-linux_gateway_page, 22b-linux_gateway_page)
894 ASM_EXCEPTIONTABLE_ENTRY(21b-linux_gateway_page, 22b-linux_gateway_page)
895#endif
896
897
898 .align PAGE_SIZE
899END(linux_gateway_page)
900ENTRY(end_linux_gateway_page)
901
902
903
904
905#define LWS_ENTRY(_name_) ASM_ULONG_INSN (lws_
906
907 .section .rodata,"a"
908
909 .align 8
910
911
912ENTRY(lws_table)
913 LWS_ENTRY(compare_and_swap32)
914 LWS_ENTRY(compare_and_swap64)
915 LWS_ENTRY(compare_and_swap_2)
916END(lws_table)
917
918
919 .align 8
920ENTRY(sys_call_table)
921 .export sys_call_table,data
922#include "syscall_table.S"
923END(sys_call_table)
924
925#ifdef CONFIG_64BIT
926 .align 8
927ENTRY(sys_call_table64)
928#define SYSCALL_TABLE_64BIT
929#include "syscall_table.S"
930END(sys_call_table64)
931#endif
932
933
934
935
936
937
938
939
940
941 .section .data
942 .align L1_CACHE_BYTES
943ENTRY(lws_lock_start)
944
945 .rept 16
946
947 .word 1
948 .word 0
949 .word 0
950 .word 0
951 .endr
952END(lws_lock_start)
953 .previous
954
955.end
956
957
958