| 1 | /* winfixup.S: Handle cases where user stack pointer is found to be bogus. |
| 2 | * |
| 3 | * Copyright (C) 1997, 2006 David S. Miller (davem@davemloft.net) |
| 4 | */ |
| 5 | |
| 6 | #include <asm/asi.h> |
| 7 | #include <asm/head.h> |
| 8 | #include <asm/page.h> |
| 9 | #include <asm/ptrace.h> |
| 10 | #include <asm/processor.h> |
| 11 | #include <asm/spitfire.h> |
| 12 | #include <asm/thread_info.h> |
| 13 | |
| 14 | .text |
| 15 | |
| 16 | /* It used to be the case that these register window fault |
| 17 | * handlers could run via the save and restore instructions |
| 18 | * done by the trap entry and exit code. They now do the |
| 19 | * window spill/fill by hand, so that case no longer can occur. |
| 20 | */ |
| 21 | |
| 22 | .align 32 |
| 23 | fill_fixup: |
| 24 | TRAP_LOAD_THREAD_REG(%g6, %g1) |
| 25 | rdpr %tstate, %g1 |
| 26 | and %g1, TSTATE_CWP, %g1 |
| 27 | or %g4, FAULT_CODE_WINFIXUP, %g4 |
| 28 | stb %g4, [%g6 + TI_FAULT_CODE] |
| 29 | stx %g5, [%g6 + TI_FAULT_ADDR] |
| 30 | wrpr %g1, %cwp |
| 31 | ba,pt %xcc, etrap |
| 32 | rd %pc, %g7 |
| 33 | call do_sparc64_fault |
| 34 | add %sp, PTREGS_OFF, %o0 |
| 35 | ba,pt %xcc, rtrap |
| 36 | nop |
| 37 | |
| 38 | /* Be very careful about usage of the trap globals here. |
| 39 | * You cannot touch %g5 as that has the fault information. |
| 40 | */ |
| 41 | spill_fixup: |
| 42 | spill_fixup_mna: |
| 43 | spill_fixup_dax: |
| 44 | TRAP_LOAD_THREAD_REG(%g6, %g1) |
| 45 | ldx [%g6 + TI_FLAGS], %g1 |
| 46 | andcc %g1, _TIF_32BIT, %g0 |
| 47 | ldub [%g6 + TI_WSAVED], %g1 |
| 48 | sll %g1, 3, %g3 |
| 49 | add %g6, %g3, %g3 |
| 50 | stx %sp, [%g3 + TI_RWIN_SPTRS] |
| 51 | sll %g1, 7, %g3 |
| 52 | bne,pt %xcc, 1f |
| 53 | add %g6, %g3, %g3 |
| 54 | stx %l0, [%g3 + TI_REG_WINDOW + 0x00] |
| 55 | stx %l1, [%g3 + TI_REG_WINDOW + 0x08] |
| 56 | stx %l2, [%g3 + TI_REG_WINDOW + 0x10] |
| 57 | stx %l3, [%g3 + TI_REG_WINDOW + 0x18] |
| 58 | stx %l4, [%g3 + TI_REG_WINDOW + 0x20] |
| 59 | stx %l5, [%g3 + TI_REG_WINDOW + 0x28] |
| 60 | stx %l6, [%g3 + TI_REG_WINDOW + 0x30] |
| 61 | stx %l7, [%g3 + TI_REG_WINDOW + 0x38] |
| 62 | stx %i0, [%g3 + TI_REG_WINDOW + 0x40] |
| 63 | stx %i1, [%g3 + TI_REG_WINDOW + 0x48] |
| 64 | stx %i2, [%g3 + TI_REG_WINDOW + 0x50] |
| 65 | stx %i3, [%g3 + TI_REG_WINDOW + 0x58] |
| 66 | stx %i4, [%g3 + TI_REG_WINDOW + 0x60] |
| 67 | stx %i5, [%g3 + TI_REG_WINDOW + 0x68] |
| 68 | stx %i6, [%g3 + TI_REG_WINDOW + 0x70] |
| 69 | ba,pt %xcc, 2f |
| 70 | stx %i7, [%g3 + TI_REG_WINDOW + 0x78] |
| 71 | 1: stw %l0, [%g3 + TI_REG_WINDOW + 0x00] |
| 72 | stw %l1, [%g3 + TI_REG_WINDOW + 0x04] |
| 73 | stw %l2, [%g3 + TI_REG_WINDOW + 0x08] |
| 74 | stw %l3, [%g3 + TI_REG_WINDOW + 0x0c] |
| 75 | stw %l4, [%g3 + TI_REG_WINDOW + 0x10] |
| 76 | stw %l5, [%g3 + TI_REG_WINDOW + 0x14] |
| 77 | stw %l6, [%g3 + TI_REG_WINDOW + 0x18] |
| 78 | stw %l7, [%g3 + TI_REG_WINDOW + 0x1c] |
| 79 | stw %i0, [%g3 + TI_REG_WINDOW + 0x20] |
| 80 | stw %i1, [%g3 + TI_REG_WINDOW + 0x24] |
| 81 | stw %i2, [%g3 + TI_REG_WINDOW + 0x28] |
| 82 | stw %i3, [%g3 + TI_REG_WINDOW + 0x2c] |
| 83 | stw %i4, [%g3 + TI_REG_WINDOW + 0x30] |
| 84 | stw %i5, [%g3 + TI_REG_WINDOW + 0x34] |
| 85 | stw %i6, [%g3 + TI_REG_WINDOW + 0x38] |
| 86 | stw %i7, [%g3 + TI_REG_WINDOW + 0x3c] |
| 87 | 2: add %g1, 1, %g1 |
| 88 | stb %g1, [%g6 + TI_WSAVED] |
| 89 | rdpr %tstate, %g1 |
| 90 | andcc %g1, TSTATE_PRIV, %g0 |
| 91 | saved |
| 92 | be,pn %xcc, 1f |
| 93 | and %g1, TSTATE_CWP, %g1 |
| 94 | retry |
| 95 | 1: mov FAULT_CODE_WRITE | FAULT_CODE_DTLB | FAULT_CODE_WINFIXUP, %g4 |
| 96 | stb %g4, [%g6 + TI_FAULT_CODE] |
| 97 | stx %g5, [%g6 + TI_FAULT_ADDR] |
| 98 | wrpr %g1, %cwp |
| 99 | ba,pt %xcc, etrap |
| 100 | rd %pc, %g7 |
| 101 | call do_sparc64_fault |
| 102 | add %sp, PTREGS_OFF, %o0 |
| 103 | ba,a,pt %xcc, rtrap |
| 104 | |
| 105 | winfix_mna: |
| 106 | andn %g3, 0x7f, %g3 |
| 107 | add %g3, 0x78, %g3 |
| 108 | wrpr %g3, %tnpc |
| 109 | done |
| 110 | |
| 111 | fill_fixup_mna: |
| 112 | rdpr %tstate, %g1 |
| 113 | and %g1, TSTATE_CWP, %g1 |
| 114 | wrpr %g1, %cwp |
| 115 | ba,pt %xcc, etrap |
| 116 | rd %pc, %g7 |
| 117 | sethi %hi(tlb_type), %g1 |
| 118 | lduw [%g1 + %lo(tlb_type)], %g1 |
| 119 | cmp %g1, 3 |
| 120 | bne,pt %icc, 1f |
| 121 | add %sp, PTREGS_OFF, %o0 |
| 122 | mov %l4, %o2 |
| 123 | call sun4v_do_mna |
| 124 | mov %l5, %o1 |
| 125 | ba,a,pt %xcc, rtrap |
| 126 | 1: mov %l4, %o1 |
| 127 | mov %l5, %o2 |
| 128 | call mem_address_unaligned |
| 129 | nop |
| 130 | ba,a,pt %xcc, rtrap |
| 131 | |
| 132 | winfix_dax: |
| 133 | andn %g3, 0x7f, %g3 |
| 134 | add %g3, 0x74, %g3 |
| 135 | wrpr %g3, %tnpc |
| 136 | done |
| 137 | |
| 138 | fill_fixup_dax: |
| 139 | rdpr %tstate, %g1 |
| 140 | and %g1, TSTATE_CWP, %g1 |
| 141 | wrpr %g1, %cwp |
| 142 | ba,pt %xcc, etrap |
| 143 | rd %pc, %g7 |
| 144 | sethi %hi(tlb_type), %g1 |
| 145 | mov %l4, %o1 |
| 146 | lduw [%g1 + %lo(tlb_type)], %g1 |
| 147 | mov %l5, %o2 |
| 148 | cmp %g1, 3 |
| 149 | bne,pt %icc, 1f |
| 150 | add %sp, PTREGS_OFF, %o0 |
| 151 | call sun4v_data_access_exception |
| 152 | nop |
| 153 | ba,a,pt %xcc, rtrap |
| 154 | 1: call spitfire_data_access_exception |
| 155 | nop |
| 156 | ba,a,pt %xcc, rtrap |