1
2
3
4
5
6
7
8
9
10
11 #include <asm/head.h>
12 #include <asm/asi.h>
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 #define TRAP_WIN_CLEAN \
40 or %g0, %g5, %l5; \
41 or %g0, %g6, %l6; \
42 or %g0, %g7, %l7; \
43 sethi %hi(_current), %g6; \
44 ld [%g6 + %lo(_current)], %g6; \
45 ld [%g6 + THREAD_UWINDOWS], %g7; \
46 subcc %g7, 0x0, %g0
47 bne 2f; \
48 save %g0, %g0, %g0; \
49 std %l0, [%sp]; \
50 1: std %l2, [%sp + 0x8]; \
51 std %l4, [%sp + 0x10]; \
52 std %l6, [%sp + 0x18]; \
53 std %i0, [%sp + 0x20]; \
54 std %i2, [%sp + 0x28]; \
55 std %i4, [%sp + 0x30]; \
56 std %i6, [%sp + 0x38]; \
57 or %g0, 0x1, %g5; \
58 rd %psr, %g7; \
59 sll %g5, %g7, %g5; \
60 wr %g5, 0x0, %wim; \
61 and %g7, 0x1f, %g7; \
62 st %g7, [%g6 + THREAD_WIM]; \
63 restore %g0, %g0, %g0; \
64 or %g0, %l5, %g5; \
65 or %g0, %l6, %g6; \
66 b 8f; \
67 or %g0, %l7, %g7; \
68 2: sub %g7, 0x1, %g7; \
69 st %g7, [%g6 + THREAD_UWINDOWS]; \
70 andcc %sp, 0x7, %g0; \
71 bne 5f; \
72 sra %sp, 0x1e, %g7; \
73 subcc %g7, 0x0, %g0; \
74 be,a 3f; \
75 andn %sp, 0xfff, %g7; \
76 subcc %g7, -1, %g0; \
77 bne 5f; \
78 andn %sp, 0xfff, %g7; \
79 3: lda [%g7] ASI_PTE, %g7; \
80 srl %g7, 0x1d, %g7; \
81 subcc %g7, 0x6, %g0; \
82 bne 5f; \
83 and %sp, 0xfff, %g7; \
84 subcc %g7, 0xfc1, %g0; \
85 bl,a 1b; \
86 std %l0, [%sp]; \
87 add %sp, 0x38, %g5; \
88 sra %g5, 0x1e, %g7; \
89 subcc %g7, 0x0, %g0; \
90 be,a 4f; \
91 andn %g5, 0xfff, %g7; \
92 subcc %g7, -1, %g0; \
93 bne 5f; \
94 andn %g5, 0xfff, %g7; \
95 4: lda [%g7] ASI_PTE, %g7; \
96 srl %g7, 0x1d, %g7; \
97 subcc %g7, 0x6, %g0; \
98 be,a 1b; \
99 std %l0, [%sp]; \
100 5: ld [%g6 + THREAD_UWINDOWS], %g7; \
101 add %g6, THREAD_REG_WINDOW, %g5; \
102 6: std %l0, [%g5]; \
103 std %l2, [%g5 + 0x8]; \
104 std %l4, [%g5 + 0x10]; \
105 std %l6, [%g5 + 0x18]; \
106 std %i0, [%g5 + 0x20]; \
107 std %i2, [%g5 + 0x28]; \
108 std %i4, [%g5 + 0x30]; \
109 std %i6, [%g5 + 0x38]; \
110 subcc %g7, 0x1, %g7; \
111 bge,a 6b; \
112 save %g5, 0x40, %g5; \
113 st %sp, [%g6 + THREAD_USP]; \
114 or %g0, 0x1, %g5; \
115 rd %psr, %g7; \
116 sll %g5, %g7, %g5; \
117 wr %g5, 0x0, %wim; \
118 and %g7, 0x1f, %g7; \
119 st %g7, [%g6 + THREAD_WIM]; \
120 ld [%g6 + THREAD_UWINDOWS], %g7; \
121 add %g7, 0x1, %g5; \
122 st %g5, [%g6 + THREAD_W_SAVED]; \
123 st %g0, [%g6 + THREAD_UWINDOWS]; \
124 7: subcc %g7, 0x1, %g7; \
125 bge 7b; \
126 restore %g0, %g0, %g0; \
127 or %g0, %l5, %g5; \
128 or %g0, %l6, %g6; \
129 or %g0, %l7, %g7; \
130 8: \
131
132
133
134
135
136
137
138
139 #define ENTER_TRAP \
140 rd %wim, %l4; \
141 or %g0, 0x1, %l5; \
142 sll %l5, %l0, %l5; \
143 andcc %l0, 0x40, %g0; \
144 bz 1f; \
145 andcc %l4, %l5, %g0; \
146 bz,a 3f; \
147 sub %fp, 0xb0, %sp; \
148 TRAP_WIN_CLEAN \
149 b 3f; \
150 sub %fp, 0xb0, %sp; \
151 1: sethi %hi(_current), %l6; \
152 ld [%l6 + %lo(_current)], %l6; \
153 ld [%l6 + THREAD_WIM], %l5; \
154 and %l0, 0x1f, %l4; \
155 cmp %l5, %l3; \
156 ble,a 4f; \
157 sethi %hi(_nwindowsm1), %l4; \
158 sub %l5, %l3, %l3; \
159 b 5f; \
160 sub %l3, 0x1, %l5; \
161 4: ld [%l4 + %lo(_nwindowsm1)], %l4; \
162 sub %l4, %l3, %l4; \
163 add %l5, %l4, %l5; \
164 5: st %l5, [%l6 + THREAD_UWINDOWS]; \
165 bz,a 2f; \
166 sethi %hi(TASK_SIZE-176), %l5; \
167 TRAP_WIN_CLEAN; \
168 sethi %hi(_current), %l6; \
169 ld [%l6 + %lo(_current)], %l6; \
170 sethi %hi(TASK_SIZE-176), %l5; \
171 2: or %l5, %lo(TASK_SIZE-176), %l5; \
172 add %l6, %l5, %sp; \
173 3: \
174
175 #define ENTER_IRQ \
176 rd %wim, %l4; \
177 or %g0, 0x1, %l5; \
178 sll %l5, %l0, %l5; \
179 andcc %l0, 0x40, %g0; \
180 bz 1f; \
181 andcc %l4, %l5, %g0; \
182 bz,a 0f; \
183 sethi %hi(_eintstack), %l7; \
184 TRAP_WIN_CLEAN \
185 sethi %hi(_eintstack), %l7; \
186 0: cmp %fp, %l7; \
187 bge,a 3f; \
188 sub %l7, 0xb0, %sp; \
189 b 3f; \
190 sub %fp, 0xb0, %sp; \
191 1: sethi %hi(_current), %l6; \
192 ld [%l6 + %lo(_current)], %l6; \
193 ld [%l6 + PCB_WIM], %l5; \
194 and %l0, 0x1f, %l7; \
195 cmp %l5, %l7; \
196 ble,a 4f; \
197 sethi %hi(_nwindowsm1), %l4; \
198 sub %l5, %l7, %l7; \
199 b 5f; \
200 sub %l7, 0x1, %l5; \
201 4: ld [%l4 + %lo(_nwindowsm1)], %l4; \
202 sub %l4, %l7, %l4; \
203 add %l5, %l4, %l5; \
204 5: st %l5, [%l6 + THREAD_UWINDOWS]; \
205 bz,a 2f; \
206 sethi %hi(_eintstack), %l7; \
207 TRAP_WIN_CLEAN; \
208 sethi %hi(_eintstack), %l7; \
209 2: \
210 sub %l7, 0xb0, %sp; \
211 3: \
212
213 .text
214 .align 4
215
216
217 .globl my_trap_handler
218 my_trap_handler:
219 rd %wim, %l4
220 or %g0, 0x1, %l5
221 sll %l5, %l0, %l5
222 cmp %l4, %l5 ! are we in the invalid window?
223
224 TRAP_WIN_CLEAN
225
226 nop
227 or %g0, %l3, %o0
228 call _do_hw_interrupt
229 or %g0, %g0, %o1
230 wr %l0, 0x20, %psr ! re-enable traps and reset the condition codes
231 nop
232 nop
233 nop ! click our heels three times, "no place like home"
234 jmp %l1
235 rett %l2
236
237
238
239
240
241
242
243
244
245
246 .globl fill_window_entry
247 fill_window_entry:
248 andcc %l0, 0x40, %g0 ! see if this is a user window fill
249 bz,a fill_from_user
250 nop
251
252 TRAP_WIN_CLEAN
253 wr %l0, 0x0, %psr
254 nop
255 jmp %l1
256 rett %l2
257
258 fill_from_user:
259 sethi %hi(_current), %l6
260 ld [%l6 + %lo(_current)], %l6
261 ld [%l6 + THREAD_WIM], %l5
262 and %l0, 0x1f, %l3
263
264
265
266
267 cmp %l5, %l3
268 ble,a 1f
269 sethi %hi(_nwindowsm1), %l4
270 sub %l5, %l3, %l3
271 b 2f
272 sub %l3, 0x1, %l5
273 1: ld [%l4 + %lo(_nwindowsm1)], %l4
274 sub %l4, %l3, %l4
275 add %l5, %l4, %l5
276 2: st %l5, [%l6 + THREAD_UWINDOWS]
277
278 TRAP_WIN_CLEAN
279 sethi %hi(_current), %l6
280 ld [%l6 + %lo(_current)], %l6
281 ld [%l6 + THREAD_KSP], %sp
282 and %l0, 0x1f, %l3
283 sethi %hi(lnx_winmask), %l6
284 or %l6, %lo(lnx_winmask), %l6
285 ldub [%l6 + %l3], %l5
286 rd %wim, %l4
287 jmp %l1
288 rett %l2
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303 .globl spill_window_entry
304 spill_window_entry:
305 wr %g0, 0, %wim ! Can not enter invalid register without this.
306 andcc %l0, 0x40, %g0 ! From user?
307 restore ! restore to where trap occurred
308 bz spill_from_user
309 restore ! enter invalid register, whee...
310 restore %g0, 0x1, %l1 ! enter one-past invalid register
311 rd %psr, %l0 ! this is the window we need to save
312 and %l0, 0x1f, %l0
313 sll %l1, %l0, %l1
314 wr %l1, 0x0, %wim
315 sethi %hi(_current), %l1
316 ld [%l1 + %lo(_current)], %l1
317 st %l0, [%l1 + THREAD_WIM]
318 save %g0, %g0, %g0 ! back to invalid register
319 ldd [%sp], %l0 ! load the window from stack
320 ldd [%sp + 8], %l2
321 ldd [%sp + 16], %l4
322 ldd [%sp + 24], %l6
323 ldd [%sp + 32], %i0
324 ldd [%sp + 40], %i2
325 ldd [%sp + 48], %i4
326 ldd [%sp + 56], %i6
327 save %g0, %g0, %g0 ! to window where trap happened
328 save %g0, %g0, %g0 ! back to trap window, so rett works
329 wr %l0, 0x0, %psr ! load condition codes
330 nop
331 jmp %l1
332 rett %l2 ! are you as confused as I am?
333
334 spill_from_user:
335 andcc %sp, 0x7, %g0 ! check for alignment of user stack
336 bne spill_bad_stack
337 sra %sp, 0x1e, %l7
338 cmp %l7, 0x0
339 be,a 1f
340 andn %sp, 0xfff, %l7
341 cmp %l7, -1
342 bne spill_bad_stack
343 andn %sp, 0xfff, %l7
344 1: lda [%l7] ASI_PTE, %l7
345 srl %l7, 0x1d, %l7
346 andn %l7, 0x2, %l7
347 cmp %l7, 0x4
348 bne spill_bad_stack
349 and %sp, 0xfff, %l7
350 cmp %l7, 0xfc1
351 bl,a spill_stack_ok
352 restore %g0, 1, %l1
353 add %sp, 0x38, %l5
354 sra %sp, 0x1e, %l7
355 cmp %l7, 0x0
356 be,a 1f
357 andn %sp, 0xfff, %l7
358 cmp %l7, -1
359 bne spill_bad_stack
360 andn %sp, 0xfff, %l7
361 1: lda [%l7] ASI_PTE, %l7
362 srl %l7, 0x1d, %l7
363 andn %l7, 0x2, %l7
364 cmp %l7, 0x4
365 be,a spill_stack_ok
366 restore %g0, 0x1, %l1
367
368 spill_bad_stack:
369 save %g0, %g0, %g0 ! save to where restore happened
370 save %g0, 0x1, %l4 ! save is an add remember? to trap window
371 sethi %hi(_current), %l6
372 ld [%l6 + %lo(_current)], %l6
373 st %l4, [%l6 + THREAD_UWINDOWS] ! update current->tss values
374 ld [%l6 + THREAD_WIM], %l5
375 sll %l4, %l5, %l4
376 wr %l4, 0x0, %wim
377 ld [%l6 + THREAD_KSP], %sp ! set to kernel stack pointer
378 wr %l0, 0x20, %psr ! turn off traps
379 std %l0, [%sp + C_STACK] ! set up thread_frame on stack
380 rd %y, %l3
381 std %l2, [%sp + C_STACK + 0x8]
382 or %g0, 0x6, %o0 ! so _sparc_trap knows what to do
383 st %g1, [%sp + C_STACK + 0x14] ! no need to save %g0, always zero
384 or %g0, %l0, %o1
385 std %g2, [%sp + C_STACK + 0x18]
386 or %g0, %l1, %o2
387 std %g4, [%sp + C_STACK + 0x20]
388 add %sp, C_STACK, %o3
389 std %g6, [%sp + C_STACK + 0x28]
390 std %i0, [%sp + C_STACK + 0x30]
391 std %i2, [%sp + C_STACK + 0x38]
392 std %i4, [%sp + C_STACK + 0x40]
393 call sparc_trap
394 std %i6, [%sp + C_STACK + 0x48]
395
396 ldd [%sp + C_STACK], %l0
397 ldd [%sp + C_STACK + 0x8], %l2
398 wr %l3, 0, %y
399 ld [%sp + C_STACK + 0x14], %g1
400 ldd [%sp + C_STACK + 0x18], %g2
401 ldd [%sp + C_STACK + 0x20], %g4
402 ldd [%sp + C_STACK + 0x28], %g6
403 ldd [%sp + C_STACK + 0x30], %i0
404 ldd [%sp + C_STACK + 0x38], %i2
405 ldd [%sp + C_STACK + 0x40], %i4
406 wr %l0, 0, %psr ! disable traps again
407 ldd [%sp + C_STACK + 0x48], %i6
408 sethi %hi(_current), %l6
409 ld [%l6 + %lo(_current)], %l6
410 ld [%l6 + THREAD_W_SAVED], %l7
411 cmp %l7, 0x0
412 bl,a 1f
413 wr %g0, 0x0, %wim
414 b,a leave_trap
415
416 1: or %g0, %g6, %l3
417 or %g0, %l6, %g6
418 st %g0, [%g6 + THREAD_W_SAVED]
419 restore %g0, %g0, %g0
420 restore %g0, %g0, %g0
421 restore %g0, 0x1, %l1
422 rd %psr, %l0
423 sll %l1, %l0, %l1
424 wr %l1, 0x0, %wim
425 and %l0, 0x1f, %l0
426 st %l0, [%g6 + THREAD_WIM]
427 nop
428 save %g0, %g0, %g0
429 ldd [%sp], %l0 ! load number one
430 ldd [%sp + 0x8], %l2
431 ldd [%sp + 0x10], %l4
432 ldd [%sp + 0x18], %l6
433 ldd [%sp + 0x20], %i0
434 ldd [%sp + 0x28], %i2
435 ldd [%sp + 0x30], %i4
436 ldd [%sp + 0x38], %i6
437 save %g0, %g0, %g0
438 ldd [%sp], %l0 ! load number two
439 ldd [%sp + 0x8], %l2
440 ldd [%sp + 0x10], %l4
441 ldd [%sp + 0x18], %l6
442 ldd [%sp + 0x20], %i0
443 ldd [%sp + 0x28], %i2
444 ldd [%sp + 0x30], %i4
445 ldd [%sp + 0x38], %i6
446 save %g0, %g0, %g0 ! re-enter trap window
447 wr %l0, 0x0, %psr ! restore condition codes
448 or %g0, %l3, %g6 ! restore scratch register
449 jmp %l1
450 rett %l2
451
452 spill_stack_ok:
453 rd %psr, %l0
454 sll %l1, %l0, %l1
455 wr %l1, 0x0, %wim
456 sethi %hi(_current), %l2
457 ld [%l2 + %lo(_current)], %l2
458 and %l0, 0x1f, %l0
459 st %l0, [%l2 + THREAD_WIM]
460 save %g0, %g0, %g0
461 ldd [%sp], %l0 ! only one load necessary
462 ldd [%sp + 0x8], %l2
463 ldd [%sp + 0x10], %l4
464 ldd [%sp + 0x18], %l6
465 ldd [%sp + 0x20], %i0
466 ldd [%sp + 0x28], %i2
467 ldd [%sp + 0x30], %i4
468 ldd [%sp + 0x38], %i6
469 save %g0, %g0, %g0
470 save %g0, %g0, %g0 ! save into trap window
471 wr %l0, 0x0, %psr ! local number 0 here has cond codes
472 nop
473 jmp %l1
474 rett %l2
475
476 .globl trap_entry
477 trap_entry:
478 TRAP_WIN_CLEAN
479 jmp %l1
480 rett %l2
481
482 .globl linux_trap_nmi
483 linux_trap_nmi:
484 TRAP_WIN_CLEAN
485 jmp %l1
486 rett %l2
487
488 .globl sparc_trap
489 sparc_trap:
490 TRAP_WIN_CLEAN
491 jmp %l1
492 rett %l2
493
494 .globl leave_trap
495 leave_trap:
496 jmp %l1
497 rett %l2
498
499
500
501
502
503
504
505
506
507
508 .data
509 .align 4
510 lnx_winmask: .byte 2, 4, 8, 16, 32, 64, 128,1 ! lnx_winmask[0..7]
511
512
513 .align 4
514 .globl _sys_call_table
515 _sys_call_table:
516 .long _sys_setup
517 .long _sys_exit
518 .long _sys_fork
519 .long _sys_read
520 .long _sys_write
521 .long _sys_open
522 .long _sys_close
523 .long _sys_waitpid
524 .long _sys_creat
525 .long _sys_link
526 .long _sys_unlink
527 .long _sys_execve
528 .long _sys_chdir
529 .long _sys_time
530 .long _sys_mknod
531 .long _sys_chmod
532 .long _sys_chown
533 .long _sys_break
534 .long _sys_stat
535 .long _sys_lseek
536 .long _sys_getpid
537 .long _sys_mount
538 .long _sys_umount
539 .long _sys_setuid
540 .long _sys_getuid
541 .long _sys_stime
542 .long _sys_ni_syscall
543 .long _sys_alarm
544 .long _sys_fstat
545 .long _sys_pause
546 .long _sys_utime
547 .long _sys_stty
548 .long _sys_gtty
549 .long _sys_access
550 .long _sys_nice
551 .long _sys_ftime
552 .long _sys_sync
553 .long _sys_kill
554 .long _sys_rename
555 .long _sys_mkdir
556 .long _sys_rmdir
557 .long _sys_dup
558 .long _sys_pipe
559 .long _sys_times
560 .long _sys_prof
561 .long _sys_brk
562 .long _sys_setgid
563 .long _sys_getgid
564 .long _sys_signal
565 .long _sys_geteuid
566 .long _sys_getegid
567 .long _sys_acct
568 .long _sys_phys
569 .long _sys_lock
570 .long _sys_ioctl
571 .long _sys_fcntl
572 .long _sys_mpx
573 .long _sys_setpgid
574 .long _sys_ulimit
575 .long _sys_olduname
576 .long _sys_umask
577 .long _sys_chroot
578 .long _sys_ustat
579 .long _sys_dup2
580 .long _sys_getppid
581 .long _sys_getpgrp
582 .long _sys_setsid
583 .long _sys_sigaction
584 .long _sys_sgetmask
585 .long _sys_ssetmask
586 .long _sys_setreuid
587 .long _sys_setregid
588 .long _sys_sigsuspend
589 .long _sys_sigpending
590 .long _sys_sethostname
591 .long _sys_setrlimit
592 .long _sys_getrlimit
593 .long _sys_getrusage
594 .long _sys_gettimeofday
595 .long _sys_settimeofday
596 .long _sys_getgroups
597 .long _sys_setgroups
598 .long _sys_select
599 .long _sys_symlink
600 .long _sys_lstat
601 .long _sys_readlink
602 .long _sys_uselib
603 .long _sys_swapon
604 .long _sys_reboot
605 .long _sys_readdir
606 .long _sys_mmap
607 .long _sys_munmap
608 .long _sys_truncate
609 .long _sys_ftruncate
610 .long _sys_fchmod
611 .long _sys_fchown
612 .long _sys_getpriority
613 .long _sys_setpriority
614 .long _sys_profil
615 .long _sys_statfs
616 .long _sys_fstatfs
617 .long _sys_ni_syscall
618 .long _sys_socketcall
619 .long _sys_syslog
620 .long _sys_setitimer
621 .long _sys_getitimer
622 .long _sys_newstat
623 .long _sys_newlstat
624 .long _sys_newfstat
625 .long _sys_uname
626 .long _sys_ni_syscall
627 .long _sys_vhangup
628 .long _sys_idle
629 .long _sys_ni_syscall
630 .long _sys_wait4
631 .long _sys_swapoff
632 .long _sys_sysinfo
633 .long _sys_ipc
634 .long _sys_fsync
635 .long _sys_sigreturn
636 .long _sys_ni_syscall
637 .long _sys_setdomainname
638 .long _sys_newuname
639 .long _sys_ni_syscall
640 .long _sys_adjtimex
641 .long _sys_mprotect
642 .long _sys_sigprocmask
643 .long _sys_create_module
644 .long _sys_init_module
645 .long _sys_delete_module
646 .long _sys_get_kernel_syms
647 .long _sys_ni_syscall
648 .long _sys_getpgid
649 .long _sys_fchdir
650 .long _sys_bdflush
651 .long _sys_sysfs
652 .long _sys_personality
653 .long 0
654 .long _sys_setfsuid
655 .long _sys_setfsgid
656 .long _sys_llseek