aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/entry.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/entry.S')
-rw-r--r--arch/sparc64/kernel/entry.S331
1 files changed, 232 insertions, 99 deletions
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index a73553ae7e53..6d0b3ed77a02 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -50,7 +50,8 @@ do_fpdis:
50 add %g0, %g0, %g0 50 add %g0, %g0, %g0
51 ba,a,pt %xcc, rtrap_clr_l6 51 ba,a,pt %xcc, rtrap_clr_l6
52 52
531: ldub [%g6 + TI_FPSAVED], %g5 531: TRAP_LOAD_THREAD_REG(%g6, %g1)
54 ldub [%g6 + TI_FPSAVED], %g5
54 wr %g0, FPRS_FEF, %fprs 55 wr %g0, FPRS_FEF, %fprs
55 andcc %g5, FPRS_FEF, %g0 56 andcc %g5, FPRS_FEF, %g0
56 be,a,pt %icc, 1f 57 be,a,pt %icc, 1f
@@ -96,10 +97,22 @@ do_fpdis:
96 add %g6, TI_FPREGS + 0x80, %g1 97 add %g6, TI_FPREGS + 0x80, %g1
97 faddd %f0, %f2, %f4 98 faddd %f0, %f2, %f4
98 fmuld %f0, %f2, %f6 99 fmuld %f0, %f2, %f6
99 ldxa [%g3] ASI_DMMU, %g5 100
101661: ldxa [%g3] ASI_DMMU, %g5
102 .section .sun4v_1insn_patch, "ax"
103 .word 661b
104 ldxa [%g3] ASI_MMU, %g5
105 .previous
106
100 sethi %hi(sparc64_kern_sec_context), %g2 107 sethi %hi(sparc64_kern_sec_context), %g2
101 ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2 108 ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2
102 stxa %g2, [%g3] ASI_DMMU 109
110661: stxa %g2, [%g3] ASI_DMMU
111 .section .sun4v_1insn_patch, "ax"
112 .word 661b
113 stxa %g2, [%g3] ASI_MMU
114 .previous
115
103 membar #Sync 116 membar #Sync
104 add %g6, TI_FPREGS + 0xc0, %g2 117 add %g6, TI_FPREGS + 0xc0, %g2
105 faddd %f0, %f2, %f8 118 faddd %f0, %f2, %f8
@@ -125,11 +138,23 @@ do_fpdis:
125 fzero %f32 138 fzero %f32
126 mov SECONDARY_CONTEXT, %g3 139 mov SECONDARY_CONTEXT, %g3
127 fzero %f34 140 fzero %f34
128 ldxa [%g3] ASI_DMMU, %g5 141
142661: ldxa [%g3] ASI_DMMU, %g5
143 .section .sun4v_1insn_patch, "ax"
144 .word 661b
145 ldxa [%g3] ASI_MMU, %g5
146 .previous
147
129 add %g6, TI_FPREGS, %g1 148 add %g6, TI_FPREGS, %g1
130 sethi %hi(sparc64_kern_sec_context), %g2 149 sethi %hi(sparc64_kern_sec_context), %g2
131 ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2 150 ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2
132 stxa %g2, [%g3] ASI_DMMU 151
152661: stxa %g2, [%g3] ASI_DMMU
153 .section .sun4v_1insn_patch, "ax"
154 .word 661b
155 stxa %g2, [%g3] ASI_MMU
156 .previous
157
133 membar #Sync 158 membar #Sync
134 add %g6, TI_FPREGS + 0x40, %g2 159 add %g6, TI_FPREGS + 0x40, %g2
135 faddd %f32, %f34, %f36 160 faddd %f32, %f34, %f36
@@ -154,10 +179,22 @@ do_fpdis:
154 nop 179 nop
1553: mov SECONDARY_CONTEXT, %g3 1803: mov SECONDARY_CONTEXT, %g3
156 add %g6, TI_FPREGS, %g1 181 add %g6, TI_FPREGS, %g1
157 ldxa [%g3] ASI_DMMU, %g5 182
183661: ldxa [%g3] ASI_DMMU, %g5
184 .section .sun4v_1insn_patch, "ax"
185 .word 661b
186 ldxa [%g3] ASI_MMU, %g5
187 .previous
188
158 sethi %hi(sparc64_kern_sec_context), %g2 189 sethi %hi(sparc64_kern_sec_context), %g2
159 ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2 190 ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2
160 stxa %g2, [%g3] ASI_DMMU 191
192661: stxa %g2, [%g3] ASI_DMMU
193 .section .sun4v_1insn_patch, "ax"
194 .word 661b
195 stxa %g2, [%g3] ASI_MMU
196 .previous
197
161 membar #Sync 198 membar #Sync
162 mov 0x40, %g2 199 mov 0x40, %g2
163 membar #Sync 200 membar #Sync
@@ -168,7 +205,13 @@ do_fpdis:
168 ldda [%g1 + %g2] ASI_BLK_S, %f48 205 ldda [%g1 + %g2] ASI_BLK_S, %f48
169 membar #Sync 206 membar #Sync
170fpdis_exit: 207fpdis_exit:
171 stxa %g5, [%g3] ASI_DMMU 208
209661: stxa %g5, [%g3] ASI_DMMU
210 .section .sun4v_1insn_patch, "ax"
211 .word 661b
212 stxa %g5, [%g3] ASI_MMU
213 .previous
214
172 membar #Sync 215 membar #Sync
173fpdis_exit2: 216fpdis_exit2:
174 wr %g7, 0, %gsr 217 wr %g7, 0, %gsr
@@ -189,6 +232,7 @@ fp_other_bounce:
189 .globl do_fpother_check_fitos 232 .globl do_fpother_check_fitos
190 .align 32 233 .align 32
191do_fpother_check_fitos: 234do_fpother_check_fitos:
235 TRAP_LOAD_THREAD_REG(%g6, %g1)
192 sethi %hi(fp_other_bounce - 4), %g7 236 sethi %hi(fp_other_bounce - 4), %g7
193 or %g7, %lo(fp_other_bounce - 4), %g7 237 or %g7, %lo(fp_other_bounce - 4), %g7
194 238
@@ -312,6 +356,7 @@ fitos_emul_fini:
312 .globl do_fptrap 356 .globl do_fptrap
313 .align 32 357 .align 32
314do_fptrap: 358do_fptrap:
359 TRAP_LOAD_THREAD_REG(%g6, %g1)
315 stx %fsr, [%g6 + TI_XFSR] 360 stx %fsr, [%g6 + TI_XFSR]
316do_fptrap_after_fsr: 361do_fptrap_after_fsr:
317 ldub [%g6 + TI_FPSAVED], %g3 362 ldub [%g6 + TI_FPSAVED], %g3
@@ -321,10 +366,22 @@ do_fptrap_after_fsr:
321 rd %gsr, %g3 366 rd %gsr, %g3
322 stx %g3, [%g6 + TI_GSR] 367 stx %g3, [%g6 + TI_GSR]
323 mov SECONDARY_CONTEXT, %g3 368 mov SECONDARY_CONTEXT, %g3
324 ldxa [%g3] ASI_DMMU, %g5 369
370661: ldxa [%g3] ASI_DMMU, %g5
371 .section .sun4v_1insn_patch, "ax"
372 .word 661b
373 ldxa [%g3] ASI_MMU, %g5
374 .previous
375
325 sethi %hi(sparc64_kern_sec_context), %g2 376 sethi %hi(sparc64_kern_sec_context), %g2
326 ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2 377 ldx [%g2 + %lo(sparc64_kern_sec_context)], %g2
327 stxa %g2, [%g3] ASI_DMMU 378
379661: stxa %g2, [%g3] ASI_DMMU
380 .section .sun4v_1insn_patch, "ax"
381 .word 661b
382 stxa %g2, [%g3] ASI_MMU
383 .previous
384
328 membar #Sync 385 membar #Sync
329 add %g6, TI_FPREGS, %g2 386 add %g6, TI_FPREGS, %g2
330 andcc %g1, FPRS_DL, %g0 387 andcc %g1, FPRS_DL, %g0
@@ -339,7 +396,13 @@ do_fptrap_after_fsr:
339 stda %f48, [%g2 + %g3] ASI_BLK_S 396 stda %f48, [%g2 + %g3] ASI_BLK_S
3405: mov SECONDARY_CONTEXT, %g1 3975: mov SECONDARY_CONTEXT, %g1
341 membar #Sync 398 membar #Sync
342 stxa %g5, [%g1] ASI_DMMU 399
400661: stxa %g5, [%g1] ASI_DMMU
401 .section .sun4v_1insn_patch, "ax"
402 .word 661b
403 stxa %g5, [%g1] ASI_MMU
404 .previous
405
343 membar #Sync 406 membar #Sync
344 ba,pt %xcc, etrap 407 ba,pt %xcc, etrap
345 wr %g0, 0, %fprs 408 wr %g0, 0, %fprs
@@ -353,8 +416,6 @@ do_fptrap_after_fsr:
353 * 416 *
354 * With this method we can do most of the cross-call tlb/cache 417 * With this method we can do most of the cross-call tlb/cache
355 * flushing very quickly. 418 * flushing very quickly.
356 *
357 * Current CPU's IRQ worklist table is locked into %g6, don't touch.
358 */ 419 */
359 .text 420 .text
360 .align 32 421 .align 32
@@ -378,6 +439,8 @@ do_ivec:
378 sllx %g2, %g4, %g2 439 sllx %g2, %g4, %g2
379 sllx %g4, 2, %g4 440 sllx %g4, 2, %g4
380 441
442 TRAP_LOAD_IRQ_WORK(%g6, %g1)
443
381 lduw [%g6 + %g4], %g5 /* g5 = irq_work(cpu, pil) */ 444 lduw [%g6 + %g4], %g5 /* g5 = irq_work(cpu, pil) */
382 stw %g5, [%g3 + 0x00] /* bucket->irq_chain = g5 */ 445 stw %g5, [%g3 + 0x00] /* bucket->irq_chain = g5 */
383 stw %g3, [%g6 + %g4] /* irq_work(cpu, pil) = bucket */ 446 stw %g3, [%g6 + %g4] /* irq_work(cpu, pil) = bucket */
@@ -399,76 +462,6 @@ do_ivec_xcall:
3991: jmpl %g3, %g0 4621: jmpl %g3, %g0
400 nop 463 nop
401 464
402 .globl save_alternate_globals
403save_alternate_globals: /* %o0 = save_area */
404 rdpr %pstate, %o5
405 andn %o5, PSTATE_IE, %o1
406 wrpr %o1, PSTATE_AG, %pstate
407 stx %g0, [%o0 + 0x00]
408 stx %g1, [%o0 + 0x08]
409 stx %g2, [%o0 + 0x10]
410 stx %g3, [%o0 + 0x18]
411 stx %g4, [%o0 + 0x20]
412 stx %g5, [%o0 + 0x28]
413 stx %g6, [%o0 + 0x30]
414 stx %g7, [%o0 + 0x38]
415 wrpr %o1, PSTATE_IG, %pstate
416 stx %g0, [%o0 + 0x40]
417 stx %g1, [%o0 + 0x48]
418 stx %g2, [%o0 + 0x50]
419 stx %g3, [%o0 + 0x58]
420 stx %g4, [%o0 + 0x60]
421 stx %g5, [%o0 + 0x68]
422 stx %g6, [%o0 + 0x70]
423 stx %g7, [%o0 + 0x78]
424 wrpr %o1, PSTATE_MG, %pstate
425 stx %g0, [%o0 + 0x80]
426 stx %g1, [%o0 + 0x88]
427 stx %g2, [%o0 + 0x90]
428 stx %g3, [%o0 + 0x98]
429 stx %g4, [%o0 + 0xa0]
430 stx %g5, [%o0 + 0xa8]
431 stx %g6, [%o0 + 0xb0]
432 stx %g7, [%o0 + 0xb8]
433 wrpr %o5, 0x0, %pstate
434 retl
435 nop
436
437 .globl restore_alternate_globals
438restore_alternate_globals: /* %o0 = save_area */
439 rdpr %pstate, %o5
440 andn %o5, PSTATE_IE, %o1
441 wrpr %o1, PSTATE_AG, %pstate
442 ldx [%o0 + 0x00], %g0
443 ldx [%o0 + 0x08], %g1
444 ldx [%o0 + 0x10], %g2
445 ldx [%o0 + 0x18], %g3
446 ldx [%o0 + 0x20], %g4
447 ldx [%o0 + 0x28], %g5
448 ldx [%o0 + 0x30], %g6
449 ldx [%o0 + 0x38], %g7
450 wrpr %o1, PSTATE_IG, %pstate
451 ldx [%o0 + 0x40], %g0
452 ldx [%o0 + 0x48], %g1
453 ldx [%o0 + 0x50], %g2
454 ldx [%o0 + 0x58], %g3
455 ldx [%o0 + 0x60], %g4
456 ldx [%o0 + 0x68], %g5
457 ldx [%o0 + 0x70], %g6
458 ldx [%o0 + 0x78], %g7
459 wrpr %o1, PSTATE_MG, %pstate
460 ldx [%o0 + 0x80], %g0
461 ldx [%o0 + 0x88], %g1
462 ldx [%o0 + 0x90], %g2
463 ldx [%o0 + 0x98], %g3
464 ldx [%o0 + 0xa0], %g4
465 ldx [%o0 + 0xa8], %g5
466 ldx [%o0 + 0xb0], %g6
467 ldx [%o0 + 0xb8], %g7
468 wrpr %o5, 0x0, %pstate
469 retl
470 nop
471
472 .globl getcc, setcc 465 .globl getcc, setcc
473getcc: 466getcc:
474 ldx [%o0 + PT_V9_TSTATE], %o1 467 ldx [%o0 + PT_V9_TSTATE], %o1
@@ -488,9 +481,24 @@ setcc:
488 retl 481 retl
489 stx %o1, [%o0 + PT_V9_TSTATE] 482 stx %o1, [%o0 + PT_V9_TSTATE]
490 483
491 .globl utrap, utrap_ill 484 .globl utrap_trap
492utrap: brz,pn %g1, etrap 485utrap_trap: /* %g3=handler,%g4=level */
486 TRAP_LOAD_THREAD_REG(%g6, %g1)
487 ldx [%g6 + TI_UTRAPS], %g1
488 brnz,pt %g1, invoke_utrap
493 nop 489 nop
490
491 ba,pt %xcc, etrap
492 rd %pc, %g7
493 mov %l4, %o1
494 call bad_trap
495 add %sp, PTREGS_OFF, %o0
496 ba,pt %xcc, rtrap
497 clr %l6
498
499invoke_utrap:
500 sllx %g3, 3, %g3
501 ldx [%g1 + %g3], %g1
494 save %sp, -128, %sp 502 save %sp, -128, %sp
495 rdpr %tstate, %l6 503 rdpr %tstate, %l6
496 rdpr %cwp, %l7 504 rdpr %cwp, %l7
@@ -500,17 +508,6 @@ utrap: brz,pn %g1, etrap
500 rdpr %tnpc, %l7 508 rdpr %tnpc, %l7
501 wrpr %g1, 0, %tnpc 509 wrpr %g1, 0, %tnpc
502 done 510 done
503utrap_ill:
504 call bad_trap
505 add %sp, PTREGS_OFF, %o0
506 ba,pt %xcc, rtrap
507 clr %l6
508
509 /* XXX Here is stuff we still need to write... -DaveM XXX */
510 .globl netbsd_syscall
511netbsd_syscall:
512 retl
513 nop
514 511
515 /* We need to carefully read the error status, ACK 512 /* We need to carefully read the error status, ACK
516 * the errors, prevent recursive traps, and pass the 513 * the errors, prevent recursive traps, and pass the
@@ -1001,7 +998,7 @@ dcpe_icpe_tl1_common:
1001 * %g3: scratch 998 * %g3: scratch
1002 * %g4: AFSR 999 * %g4: AFSR
1003 * %g5: AFAR 1000 * %g5: AFAR
1004 * %g6: current thread ptr 1001 * %g6: unused, will have current thread ptr after etrap
1005 * %g7: scratch 1002 * %g7: scratch
1006 */ 1003 */
1007__cheetah_log_error: 1004__cheetah_log_error:
@@ -1539,13 +1536,14 @@ ret_from_syscall:
1539 1536
15401: b,pt %xcc, ret_sys_call 15371: b,pt %xcc, ret_sys_call
1541 ldx [%sp + PTREGS_OFF + PT_V9_I0], %o0 1538 ldx [%sp + PTREGS_OFF + PT_V9_I0], %o0
1542sparc_exit: wrpr %g0, (PSTATE_RMO | PSTATE_PEF | PSTATE_PRIV), %pstate 1539sparc_exit: rdpr %pstate, %g2
1540 wrpr %g2, PSTATE_IE, %pstate
1543 rdpr %otherwin, %g1 1541 rdpr %otherwin, %g1
1544 rdpr %cansave, %g3 1542 rdpr %cansave, %g3
1545 add %g3, %g1, %g3 1543 add %g3, %g1, %g3
1546 wrpr %g3, 0x0, %cansave 1544 wrpr %g3, 0x0, %cansave
1547 wrpr %g0, 0x0, %otherwin 1545 wrpr %g0, 0x0, %otherwin
1548 wrpr %g0, (PSTATE_RMO | PSTATE_PEF | PSTATE_PRIV | PSTATE_IE), %pstate 1546 wrpr %g2, 0x0, %pstate
1549 ba,pt %xcc, sys_exit 1547 ba,pt %xcc, sys_exit
1550 stb %g0, [%g6 + TI_WSAVED] 1548 stb %g0, [%g6 + TI_WSAVED]
1551 1549
@@ -1690,3 +1688,138 @@ __flushw_user:
1690 restore %g0, %g0, %g0 1688 restore %g0, %g0, %g0
16912: retl 16892: retl
1692 nop 1690 nop
1691
1692#ifdef CONFIG_SMP
1693 .globl hard_smp_processor_id
1694hard_smp_processor_id:
1695#endif
1696 .globl real_hard_smp_processor_id
1697real_hard_smp_processor_id:
1698 __GET_CPUID(%o0)
1699 retl
1700 nop
1701
1702 /* %o0: devhandle
1703 * %o1: devino
1704 *
1705 * returns %o0: sysino
1706 */
1707 .globl sun4v_devino_to_sysino
1708sun4v_devino_to_sysino:
1709 mov HV_FAST_INTR_DEVINO2SYSINO, %o5
1710 ta HV_FAST_TRAP
1711 retl
1712 mov %o1, %o0
1713
1714 /* %o0: sysino
1715 *
1716 * returns %o0: intr_enabled (HV_INTR_{DISABLED,ENABLED})
1717 */
1718 .globl sun4v_intr_getenabled
1719sun4v_intr_getenabled:
1720 mov HV_FAST_INTR_GETENABLED, %o5
1721 ta HV_FAST_TRAP
1722 retl
1723 mov %o1, %o0
1724
1725 /* %o0: sysino
1726 * %o1: intr_enabled (HV_INTR_{DISABLED,ENABLED})
1727 */
1728 .globl sun4v_intr_setenabled
1729sun4v_intr_setenabled:
1730 mov HV_FAST_INTR_SETENABLED, %o5
1731 ta HV_FAST_TRAP
1732 retl
1733 nop
1734
1735 /* %o0: sysino
1736 *
1737 * returns %o0: intr_state (HV_INTR_STATE_*)
1738 */
1739 .globl sun4v_intr_getstate
1740sun4v_intr_getstate:
1741 mov HV_FAST_INTR_GETSTATE, %o5
1742 ta HV_FAST_TRAP
1743 retl
1744 mov %o1, %o0
1745
1746 /* %o0: sysino
1747 * %o1: intr_state (HV_INTR_STATE_*)
1748 */
1749 .globl sun4v_intr_setstate
1750sun4v_intr_setstate:
1751 mov HV_FAST_INTR_SETSTATE, %o5
1752 ta HV_FAST_TRAP
1753 retl
1754 nop
1755
1756 /* %o0: sysino
1757 *
1758 * returns %o0: cpuid
1759 */
1760 .globl sun4v_intr_gettarget
1761sun4v_intr_gettarget:
1762 mov HV_FAST_INTR_GETTARGET, %o5
1763 ta HV_FAST_TRAP
1764 retl
1765 mov %o1, %o0
1766
1767 /* %o0: sysino
1768 * %o1: cpuid
1769 */
1770 .globl sun4v_intr_settarget
1771sun4v_intr_settarget:
1772 mov HV_FAST_INTR_SETTARGET, %o5
1773 ta HV_FAST_TRAP
1774 retl
1775 nop
1776
1777 /* %o0: type
1778 * %o1: queue paddr
1779 * %o2: num queue entries
1780 *
1781 * returns %o0: status
1782 */
1783 .globl sun4v_cpu_qconf
1784sun4v_cpu_qconf:
1785 mov HV_FAST_CPU_QCONF, %o5
1786 ta HV_FAST_TRAP
1787 retl
1788 nop
1789
1790 /* returns %o0: status
1791 */
1792 .globl sun4v_cpu_yield
1793sun4v_cpu_yield:
1794 mov HV_FAST_CPU_YIELD, %o5
1795 ta HV_FAST_TRAP
1796 retl
1797 nop
1798
1799 /* %o0: num cpus in cpu list
1800 * %o1: cpu list paddr
1801 * %o2: mondo block paddr
1802 *
1803 * returns %o0: status
1804 */
1805 .globl sun4v_cpu_mondo_send
1806sun4v_cpu_mondo_send:
1807 mov HV_FAST_CPU_MONDO_SEND, %o5
1808 ta HV_FAST_TRAP
1809 retl
1810 nop
1811
1812 /* %o0: CPU ID
1813 *
1814 * returns %o0: -status if status non-zero, else
1815 * %o0: cpu state as HV_CPU_STATE_*
1816 */
1817 .globl sun4v_cpu_state
1818sun4v_cpu_state:
1819 mov HV_FAST_CPU_STATE, %o5
1820 ta HV_FAST_TRAP
1821 brnz,pn %o0, 1f
1822 sub %g0, %o0, %o0
1823 mov %o1, %o0
18241: retl
1825 nop