123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- .align 32
- .globl __flushw_user
- .type __flushw_user,#function
- __flushw_user:
- rdpr %otherwin, %g1
- brz,pn %g1, 2f
- clr %g2
- 1: save %sp, -128, %sp
- rdpr %otherwin, %g1
- brnz,pt %g1, 1b
- add %g2, 1, %g2
- 1: sub %g2, 1, %g2
- brnz,pt %g2, 1b
- restore %g0, %g0, %g0
- 2: retl
- nop
- .size __flushw_user,.-__flushw_user
- /* Flush %fp and %i7 to the stack for all register
- * windows active inside of the cpu. This allows
- * show_stack_trace() to avoid using an expensive
- * 'flushw'.
- */
- .globl stack_trace_flush
- .type stack_trace_flush,#function
- stack_trace_flush:
- rdpr %pstate, %o0
- wrpr %o0, PSTATE_IE, %pstate
- rdpr %cwp, %g1
- rdpr %canrestore, %g2
- sub %g1, 1, %g3
- 1: brz,pn %g2, 2f
- sub %g2, 1, %g2
- wrpr %g3, %cwp
- stx %fp, [%sp + STACK_BIAS + RW_V9_I6]
- stx %i7, [%sp + STACK_BIAS + RW_V9_I7]
- ba,pt %xcc, 1b
- sub %g3, 1, %g3
- 2: wrpr %g1, %cwp
- wrpr %o0, %pstate
- retl
- nop
- .size stack_trace_flush,.-stack_trace_flush
- #ifdef CONFIG_PERF_EVENTS
- .globl perf_arch_fetch_caller_regs
- .type perf_arch_fetch_caller_regs,#function
- perf_arch_fetch_caller_regs:
- /* We always read the %pstate into %o5 since we will use
- * that to construct a fake %tstate to store into the regs.
- */
- rdpr %pstate, %o5
- brz,pn %o2, 50f
- mov %o2, %g7
- /* Turn off interrupts while we walk around the register
- * window by hand.
- */
- wrpr %o5, PSTATE_IE, %pstate
- /* The %canrestore tells us how many register windows are
- * still live in the chip above us, past that we have to
- * walk the frame as saved on the stack. We stash away
- * the %cwp in %g1 so we can return back to the original
- * register window.
- */
- rdpr %cwp, %g1
- rdpr %canrestore, %g2
- sub %g1, 1, %g3
- /* We have the skip count in %g7, if it hits zero then
- * %fp/%i7 are the registers we need. Otherwise if our
- * %canrestore count maintained in %g2 hits zero we have
- * to start traversing the stack.
- */
- 10: brz,pn %g2, 4f
- sub %g2, 1, %g2
- wrpr %g3, %cwp
- subcc %g7, 1, %g7
- bne,pt %xcc, 10b
- sub %g3, 1, %g3
- /* We found the values we need in the cpu's register
- * windows.
- */
- mov %fp, %g3
- ba,pt %xcc, 3f
- mov %i7, %g2
- 50: mov %fp, %g3
- ba,pt %xcc, 2f
- mov %i7, %g2
- /* We hit the end of the valid register windows in the
- * cpu, start traversing the stack frame.
- */
- 4: mov %fp, %g3
- 20: ldx [%g3 + STACK_BIAS + RW_V9_I7], %g2
- subcc %g7, 1, %g7
- bne,pn %xcc, 20b
- ldx [%g3 + STACK_BIAS + RW_V9_I6], %g3
- /* Restore the current register window position and
- * re-enable interrupts.
- */
- 3: wrpr %g1, %cwp
- wrpr %o5, %pstate
- 2: stx %g3, [%o0 + PT_V9_FP]
- sllx %o5, 8, %o5
- stx %o5, [%o0 + PT_V9_TSTATE]
- stx %g2, [%o0 + PT_V9_TPC]
- add %g2, 4, %g2
- retl
- stx %g2, [%o0 + PT_V9_TNPC]
- .size perf_arch_fetch_caller_regs,.-perf_arch_fetch_caller_regs
- #endif /* CONFIG_PERF_EVENTS */
- #ifdef CONFIG_SMP
- .globl hard_smp_processor_id
- .type hard_smp_processor_id,#function
- hard_smp_processor_id:
- #endif
- .globl real_hard_smp_processor_id
- .type real_hard_smp_processor_id,#function
- real_hard_smp_processor_id:
- __GET_CPUID(%o0)
- retl
- nop
- #ifdef CONFIG_SMP
- .size hard_smp_processor_id,.-hard_smp_processor_id
- #endif
- .size real_hard_smp_processor_id,.-real_hard_smp_processor_id
|