xref: /linux/arch/sparc/kernel/ivec.S (revision ae22a94997b8a03dcb3c922857c203246711f9d4)
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