diff options
Diffstat (limited to 'arch/sparc64/kernel/entry.S')
-rw-r--r-- | arch/sparc64/kernel/entry.S | 122 |
1 files changed, 105 insertions, 17 deletions
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index a73553ae7e53..906b64ffdb1b 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 | ||
53 | 1: ldub [%g6 + TI_FPSAVED], %g5 | 53 | 1: TRAP_LOAD_THREAD_REG |
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 |
@@ -189,6 +190,7 @@ fp_other_bounce: | |||
189 | .globl do_fpother_check_fitos | 190 | .globl do_fpother_check_fitos |
190 | .align 32 | 191 | .align 32 |
191 | do_fpother_check_fitos: | 192 | do_fpother_check_fitos: |
193 | TRAP_LOAD_THREAD_REG | ||
192 | sethi %hi(fp_other_bounce - 4), %g7 | 194 | sethi %hi(fp_other_bounce - 4), %g7 |
193 | or %g7, %lo(fp_other_bounce - 4), %g7 | 195 | or %g7, %lo(fp_other_bounce - 4), %g7 |
194 | 196 | ||
@@ -353,8 +355,6 @@ do_fptrap_after_fsr: | |||
353 | * | 355 | * |
354 | * With this method we can do most of the cross-call tlb/cache | 356 | * With this method we can do most of the cross-call tlb/cache |
355 | * flushing very quickly. | 357 | * flushing very quickly. |
356 | * | ||
357 | * Current CPU's IRQ worklist table is locked into %g6, don't touch. | ||
358 | */ | 358 | */ |
359 | .text | 359 | .text |
360 | .align 32 | 360 | .align 32 |
@@ -378,6 +378,8 @@ do_ivec: | |||
378 | sllx %g2, %g4, %g2 | 378 | sllx %g2, %g4, %g2 |
379 | sllx %g4, 2, %g4 | 379 | sllx %g4, 2, %g4 |
380 | 380 | ||
381 | TRAP_LOAD_IRQ_WORK | ||
382 | |||
381 | lduw [%g6 + %g4], %g5 /* g5 = irq_work(cpu, pil) */ | 383 | lduw [%g6 + %g4], %g5 /* g5 = irq_work(cpu, pil) */ |
382 | stw %g5, [%g3 + 0x00] /* bucket->irq_chain = g5 */ | 384 | stw %g5, [%g3 + 0x00] /* bucket->irq_chain = g5 */ |
383 | stw %g3, [%g6 + %g4] /* irq_work(cpu, pil) = bucket */ | 385 | stw %g3, [%g6 + %g4] /* irq_work(cpu, pil) = bucket */ |
@@ -488,9 +490,24 @@ setcc: | |||
488 | retl | 490 | retl |
489 | stx %o1, [%o0 + PT_V9_TSTATE] | 491 | stx %o1, [%o0 + PT_V9_TSTATE] |
490 | 492 | ||
491 | .globl utrap, utrap_ill | 493 | .globl utrap_trap |
492 | utrap: brz,pn %g1, etrap | 494 | utrap_trap: /* %g3=handler,%g4=level */ |
495 | TRAP_LOAD_THREAD_REG | ||
496 | ldx [%g6 + TI_UTRAPS], %g1 | ||
497 | brnz,pt %g1, invoke_utrap | ||
493 | nop | 498 | nop |
499 | |||
500 | ba,pt %xcc, etrap | ||
501 | rd %pc, %g7 | ||
502 | mov %l4, %o1 | ||
503 | call bad_trap | ||
504 | add %sp, PTREGS_OFF, %o0 | ||
505 | ba,pt %xcc, rtrap | ||
506 | clr %l6 | ||
507 | |||
508 | invoke_utrap: | ||
509 | sllx %g3, 3, %g3 | ||
510 | ldx [%g1 + %g3], %g1 | ||
494 | save %sp, -128, %sp | 511 | save %sp, -128, %sp |
495 | rdpr %tstate, %l6 | 512 | rdpr %tstate, %l6 |
496 | rdpr %cwp, %l7 | 513 | rdpr %cwp, %l7 |
@@ -500,17 +517,6 @@ utrap: brz,pn %g1, etrap | |||
500 | rdpr %tnpc, %l7 | 517 | rdpr %tnpc, %l7 |
501 | wrpr %g1, 0, %tnpc | 518 | wrpr %g1, 0, %tnpc |
502 | done | 519 | done |
503 | utrap_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 | ||
511 | netbsd_syscall: | ||
512 | retl | ||
513 | nop | ||
514 | 520 | ||
515 | /* We need to carefully read the error status, ACK | 521 | /* We need to carefully read the error status, ACK |
516 | * the errors, prevent recursive traps, and pass the | 522 | * the errors, prevent recursive traps, and pass the |
@@ -1001,7 +1007,7 @@ dcpe_icpe_tl1_common: | |||
1001 | * %g3: scratch | 1007 | * %g3: scratch |
1002 | * %g4: AFSR | 1008 | * %g4: AFSR |
1003 | * %g5: AFAR | 1009 | * %g5: AFAR |
1004 | * %g6: current thread ptr | 1010 | * %g6: unused, will have current thread ptr after etrap |
1005 | * %g7: scratch | 1011 | * %g7: scratch |
1006 | */ | 1012 | */ |
1007 | __cheetah_log_error: | 1013 | __cheetah_log_error: |
@@ -1690,3 +1696,85 @@ __flushw_user: | |||
1690 | restore %g0, %g0, %g0 | 1696 | restore %g0, %g0, %g0 |
1691 | 2: retl | 1697 | 2: retl |
1692 | nop | 1698 | nop |
1699 | |||
1700 | /* Read cpu ID from hardware, return in %g6. | ||
1701 | * (callers_pc - 4) is in %g1. Patched at boot time. | ||
1702 | * | ||
1703 | * Default is spitfire implementation. | ||
1704 | * | ||
1705 | * The instruction sequence needs to be 5 instructions | ||
1706 | * in order to fit the longest implementation, which is | ||
1707 | * currently starfire. | ||
1708 | */ | ||
1709 | .align 32 | ||
1710 | .globl __get_cpu_id | ||
1711 | __get_cpu_id: | ||
1712 | ldxa [%g0] ASI_UPA_CONFIG, %g6 | ||
1713 | srlx %g6, 17, %g6 | ||
1714 | jmpl %g1 + 0x4, %g0 | ||
1715 | and %g6, 0x1f, %g6 | ||
1716 | nop | ||
1717 | |||
1718 | __get_cpu_id_cheetah_safari: | ||
1719 | ldxa [%g0] ASI_SAFARI_CONFIG, %g6 | ||
1720 | srlx %g6, 17, %g6 | ||
1721 | jmpl %g1 + 0x4, %g0 | ||
1722 | and %g6, 0x3ff, %g6 | ||
1723 | nop | ||
1724 | |||
1725 | __get_cpu_id_cheetah_jbus: | ||
1726 | ldxa [%g0] ASI_JBUS_CONFIG, %g6 | ||
1727 | srlx %g6, 17, %g6 | ||
1728 | jmpl %g1 + 0x4, %g0 | ||
1729 | and %g6, 0x1f, %g6 | ||
1730 | nop | ||
1731 | |||
1732 | __get_cpu_id_starfire: | ||
1733 | sethi %hi(0x1fff40000d0 >> 9), %g6 | ||
1734 | sllx %g6, 9, %g6 | ||
1735 | or %g6, 0xd0, %g6 | ||
1736 | jmpl %g1 + 0x4, %g0 | ||
1737 | lduwa [%g6] ASI_PHYS_BYPASS_EC_E, %g6 | ||
1738 | |||
1739 | .globl per_cpu_patch | ||
1740 | per_cpu_patch: | ||
1741 | sethi %hi(this_is_starfire), %o0 | ||
1742 | lduw [%o0 + %lo(this_is_starfire)], %o1 | ||
1743 | sethi %hi(__get_cpu_id_starfire), %o0 | ||
1744 | brnz,pn %o1, 10f | ||
1745 | or %o0, %lo(__get_cpu_id_starfire), %o0 | ||
1746 | sethi %hi(tlb_type), %o0 | ||
1747 | lduw [%o0 + %lo(tlb_type)], %o1 | ||
1748 | brz,pt %o1, 11f | ||
1749 | nop | ||
1750 | rdpr %ver, %o0 | ||
1751 | srlx %o0, 32, %o0 | ||
1752 | sethi %hi(0x003e0016), %o1 | ||
1753 | or %o1, %lo(0x003e0016), %o1 | ||
1754 | cmp %o0, %o1 | ||
1755 | sethi %hi(__get_cpu_id_cheetah_jbus), %o0 | ||
1756 | be,pn %icc, 10f | ||
1757 | or %o0, %lo(__get_cpu_id_cheetah_jbus), %o0 | ||
1758 | sethi %hi(__get_cpu_id_cheetah_safari), %o0 | ||
1759 | or %o0, %lo(__get_cpu_id_cheetah_safari), %o0 | ||
1760 | 10: | ||
1761 | sethi %hi(__get_cpu_id), %o1 | ||
1762 | or %o1, %lo(__get_cpu_id), %o1 | ||
1763 | lduw [%o0 + 0x00], %o2 | ||
1764 | stw %o2, [%o1 + 0x00] | ||
1765 | flush %o1 + 0x00 | ||
1766 | lduw [%o0 + 0x04], %o2 | ||
1767 | stw %o2, [%o1 + 0x04] | ||
1768 | flush %o1 + 0x04 | ||
1769 | lduw [%o0 + 0x08], %o2 | ||
1770 | stw %o2, [%o1 + 0x08] | ||
1771 | flush %o1 + 0x08 | ||
1772 | lduw [%o0 + 0x0c], %o2 | ||
1773 | stw %o2, [%o1 + 0x0c] | ||
1774 | flush %o1 + 0x0c | ||
1775 | lduw [%o0 + 0x10], %o2 | ||
1776 | stw %o2, [%o1 + 0x10] | ||
1777 | flush %o1 + 0x10 | ||
1778 | 11: | ||
1779 | retl | ||
1780 | nop | ||