1/* SPDX-License-Identifier: GPL-2.0 */
2 /* The registers for cross calls will be:
3 *
4 * DATA 0: [low 32-bits] Address of function to call, jmp to this
5 * [high 32-bits] MMU Context Argument 0, place in %g5
6 * DATA 1: Address Argument 1, place in %g1
7 * DATA 2: Address Argument 2, place in %g7
8 *
9 * With this method we can do most of the cross-call tlb/cache
10 * flushing very quickly.
11 */
12 .align 32
13 .globl do_ivec
14 .type do_ivec,#function
15do_ivec:
16 mov 0x40, %g3
17 ldxa [%g3 + %g0] ASI_INTR_R, %g3
18 sethi %hi(KERNBASE), %g4
19 cmp %g3, %g4
20 bgeu,pn %xcc, do_ivec_xcall
21 srlx %g3, 32, %g5
22 stxa %g0, [%g0] ASI_INTR_RECEIVE
23 membar #Sync
24
25 sethi %hi(ivector_table_pa), %g2
26 ldx [%g2 + %lo(ivector_table_pa)], %g2
27 sllx %g3, 4, %g3
28 add %g2, %g3, %g3
29
30 TRAP_LOAD_IRQ_WORK_PA(%g6, %g1)
31
32 ldx [%g6], %g5
33 stxa %g5, [%g3] ASI_PHYS_USE_EC
34 stx %g3, [%g6]
35 wr %g0, 1 << PIL_DEVICE_IRQ, %set_softint
36 retry
37do_ivec_xcall:
38 mov 0x50, %g1
39 ldxa [%g1 + %g0] ASI_INTR_R, %g1
40 srl %g3, 0, %g3
41
42 mov 0x60, %g7
43 ldxa [%g7 + %g0] ASI_INTR_R, %g7
44 stxa %g0, [%g0] ASI_INTR_RECEIVE
45 membar #Sync
46 ba,pt %xcc, 1f
47 nop
48
49 .align 32
501: jmpl %g3, %g0
51 nop
52 .size do_ivec,.-do_ivec
53

source code of linux/arch/sparc/kernel/ivec.S