xref: /illumos-gate/usr/src/uts/sun4u/opl/ml/drmach_asm.S (revision 5d9d9091)
125cf1a30Sjl/*
225cf1a30Sjl * CDDL HEADER START
325cf1a30Sjl *
425cf1a30Sjl * The contents of this file are subject to the terms of the
525cf1a30Sjl * Common Development and Distribution License (the "License").
625cf1a30Sjl * You may not use this file except in compliance with the License.
725cf1a30Sjl *
825cf1a30Sjl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
925cf1a30Sjl * or http://www.opensolaris.org/os/licensing.
1025cf1a30Sjl * See the License for the specific language governing permissions
1125cf1a30Sjl * and limitations under the License.
1225cf1a30Sjl *
1325cf1a30Sjl * When distributing Covered Code, include this CDDL HEADER in each
1425cf1a30Sjl * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1525cf1a30Sjl * If applicable, add the following below this CDDL HEADER, with the
1625cf1a30Sjl * fields enclosed by brackets "[]" replaced with your own identifying
1725cf1a30Sjl * information: Portions Copyright [yyyy] [name of copyright owner]
1825cf1a30Sjl *
1925cf1a30Sjl * CDDL HEADER END
2025cf1a30Sjl */
2107d06da5SSurya Prakki
2225cf1a30Sjl/*
2307d06da5SSurya Prakki * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
2425cf1a30Sjl * Use is subject to license terms.
2525cf1a30Sjl */
2625cf1a30Sjl
2725cf1a30Sjl/*
2825cf1a30Sjl * This file is through cpp before being used as
2925cf1a30Sjl * an inline.  It contains support routines used
3025cf1a30Sjl * only by DR for the copy-rename sequence.
3125cf1a30Sjl */
3225cf1a30Sjl
3325cf1a30Sjl#include "assym.h"
3425cf1a30Sjl#include "drmach_offsets.h"
3525cf1a30Sjl
3625cf1a30Sjl#include <sys/asm_linkage.h>
3725cf1a30Sjl#include <sys/param.h>
3825cf1a30Sjl#include <sys/privregs.h>
3925cf1a30Sjl#include <sys/spitregs.h>
4025cf1a30Sjl#include <sys/mmu.h>
4125cf1a30Sjl#include <sys/machthread.h>
4225cf1a30Sjl#include <sys/pte.h>
4325cf1a30Sjl#include <sys/stack.h>
4425cf1a30Sjl#include <sys/vis.h>
4525cf1a30Sjl#include <sys/intreg.h>
4625cf1a30Sjl#include <sys/cheetahregs.h>
4725cf1a30Sjl#include <sys/drmach.h>
48b307f191Sbm#include <sys/sbd_ioctl.h>
4925cf1a30Sjl
5025cf1a30Sjl/*
5125cf1a30Sjl * turn off speculative mode to prevent unwanted memory access
5225cf1a30Sjl * when we are in the FMEM loops
5325cf1a30Sjl */
5425cf1a30Sjl
5525cf1a30Sjl#define	FJSV_SPECULATIVE_OFF(reg, tmp1, tmp2)				\
5625cf1a30Sjl	rdpr	%pstate, reg						;\
5725cf1a30Sjl	andn	reg, PSTATE_IE, tmp1					;\
5825cf1a30Sjl	wrpr	%g0, tmp1, %pstate					;\
5925cf1a30Sjl	ldxa	[%g0]ASI_MCNTL, tmp1					;\
6025cf1a30Sjl	set	1, tmp2							;\
6125cf1a30Sjl	sllx	tmp2, MCNTL_SPECULATIVE_SHIFT, tmp2						;\
6225cf1a30Sjl	or	tmp1, tmp2, tmp1					;\
6325cf1a30Sjl	stxa	tmp1, [%g0]ASI_MCNTL					;\
6425cf1a30Sjl	membar #Sync
6525cf1a30Sjl
6625cf1a30Sjl
6725cf1a30Sjl	.align  8
6825cf1a30Sjl	ENTRY_NP(drmach_fmem_loop_script)
6925cf1a30Sjl	/* turn off speculative mode */
7025cf1a30Sjl	FJSV_SPECULATIVE_OFF(%o5, %o3, %o4);
7125cf1a30Sjl
7225cf1a30Sjl	/* read the critical region to get everything in the cache */
7325cf1a30Sjl	mov	%o0, %o3
7425cf1a30Sjl0:
7525cf1a30Sjl	ldx	[%o3], %o4
7625cf1a30Sjl	sub	%o1, 8, %o1
7725cf1a30Sjl	brnz	%o1, 0b
7825cf1a30Sjl	 add	%o3, 8, %o3
7925cf1a30Sjl
8025cf1a30Sjl	/* clear L2_CTRL_UGE_TRAP error bit */
8125cf1a30Sjl	mov	ASI_L2_CTRL_RW_ADDR, %o1
8225cf1a30Sjl	ldxa	[%o1]ASI_L2_CTRL, %o3
8325cf1a30Sjl	sethi	%hi(ASI_L2_CTRL_UGE_TRAP), %o4
8425cf1a30Sjl	btst	%o3, %o4
8525cf1a30Sjl	bz,pn	%xcc, 1f
8625cf1a30Sjl	 nop
8725cf1a30Sjl	stxa	%o4, [%o1]ASI_L2_CTRL
8825cf1a30Sjl
8925cf1a30Sjl	/* now tell the master CPU that we are ready */
9025cf1a30Sjl1:
9125cf1a30Sjl	set	FMEM_LOOP_FMEM_READY, %o3
9225cf1a30Sjl	stb	%o3, [%o2]
9325cf1a30Sjl	membar #Sync
9425cf1a30Sjl	ba	 5f
9525cf1a30Sjl	 nop
9625cf1a30Sjl
9725cf1a30Sjl	/*
9825cf1a30Sjl	 * note that we branch to 5f, which branches right back to 2 here.
9925cf1a30Sjl	 * The trick is that when that branch instruction has already been
10025cf1a30Sjl	 * patched to a branch to itself - an infinite loop.
10125cf1a30Sjl	 * The master thread will patch it back to "ba 2b" when it
10225cf1a30Sjl	 * completes.
10325cf1a30Sjl	 */
10425cf1a30Sjl
10525cf1a30Sjl	/* Once we are back, we first check if there has been any
10625cf1a30Sjl	 * L2_CTRL_UGE_TRAP errors, if so we have to fail the
10725cf1a30Sjl	 * operation.  This will cause a panic because the system
10825cf1a30Sjl	 * is already in inconsistent state.
10925cf1a30Sjl	 */
11025cf1a30Sjl2:
11125cf1a30Sjl	mov	ASI_L2_CTRL_RW_ADDR, %o3
11225cf1a30Sjl	ldxa	[%o3]ASI_L2_CTRL, %o3
11325cf1a30Sjl	sethi	%hi(ASI_L2_CTRL_UGE_TRAP), %o4
11425cf1a30Sjl	btst	%o3, %o4
11525cf1a30Sjl	bz,pn	%xcc, 3f
11625cf1a30Sjl	 mov	%g0, %o4
117b307f191Sbm	set	EOPL_FMEM_HW_ERROR, %o4
11825cf1a30Sjl
11925cf1a30Sjl	/* set error code and stat code */
12025cf1a30Sjl3:
12125cf1a30Sjl	set	FMEM_LOOP_DONE, %o3
12225cf1a30Sjl	stb	%o3, [%o2]
12325cf1a30Sjl
12425cf1a30Sjl	/* turn on speculative mode again */
12525cf1a30Sjl	ldxa	[%g0]ASI_MCNTL, %o0
12625cf1a30Sjl	set	1, %o1
12725cf1a30Sjl	sllx	%o1, MCNTL_SPECULATIVE_SHIFT, %o1
12825cf1a30Sjl	andn	%o0, %o1, %o0
12925cf1a30Sjl	ba	4f
13025cf1a30Sjl	 nop
13125cf1a30Sjl.align 32
13225cf1a30Sjl4:
13325cf1a30Sjl	stxa	%o0, [%g0]ASI_MCNTL
13425cf1a30Sjl	membar	#Sync
13525cf1a30Sjl	wrpr	%g0, %o5, %pstate
13625cf1a30Sjl	retl
13725cf1a30Sjl	 mov	%o4, %o0
13825cf1a30Sjl.align 8
13925cf1a30Sjl5:
14025cf1a30Sjl	ALTENTRY(drmach_fmem_loop_script_rtn)
14125cf1a30Sjl	/*
14225cf1a30Sjl	 * busy wait will affect sibling strands so
14325cf1a30Sjl	 * we put sleep instruction in the delay slot
14425cf1a30Sjl	 */
14525cf1a30Sjl	ba	2b
14625cf1a30Sjl.word	 0x81b01060
14725cf1a30Sjl	SET_SIZE(drmach_fmem_loop_script)
1489b0bb795SJohn Levon
14925cf1a30Sjl	.align  8
15025cf1a30Sjl	ENTRY_NP(drmach_flush_icache)
15125cf1a30Sjl	stxa	%g0, [%g0]ASI_ALL_FLUSH_L1I
15225cf1a30Sjl	membar	#Sync
15325cf1a30Sjl	retl
15425cf1a30Sjl	 nop
15525cf1a30Sjl	SET_SIZE(drmach_flush_icache)
1569b0bb795SJohn Levon
15725cf1a30Sjl.align 32
15825cf1a30Sjl	ENTRY_NP(drmach_fmem_exec_script)
15925cf1a30Sjl	/* turn off speculative mode */
16025cf1a30Sjl	FJSV_SPECULATIVE_OFF(%o5, %o3, %o4);
16125cf1a30Sjl	/* save locals to save area */
16225cf1a30Sjl	add	%o0, SAVE_LOCAL, %o2
16325cf1a30Sjl	stx	%l0, [%o2+8*0]
16425cf1a30Sjl	stx	%l1, [%o2+8*1]
16525cf1a30Sjl	stx	%l2, [%o2+8*2]
16625cf1a30Sjl	stx	%l3, [%o2+8*3]
16725cf1a30Sjl	stx	%l4, [%o2+8*4]
16825cf1a30Sjl	stx	%l5, [%o2+8*5]
16925cf1a30Sjl	stx	%l6, [%o2+8*6]
17025cf1a30Sjl	stx	%l7, [%o2+8*7]
17125cf1a30Sjl	mov	%o5, %l6
17225cf1a30Sjl	/* l7 is set only when FMEM cmd is issued to SCF */
17325cf1a30Sjl	mov	%g0, %l7
17425cf1a30Sjl
17525cf1a30Sjl	/* read the critical region to put everything in the cache */
17625cf1a30Sjl	mov	%o0, %o2
17725cf1a30Sjl0:
17825cf1a30Sjl	ldx	[%o2], %o4
17925cf1a30Sjl	sub	%o1, 8, %o1
18025cf1a30Sjl	brnz	%o1, 0b
18125cf1a30Sjl	 add	%o2, 8, %o2
18225cf1a30Sjl	ba	4f
18325cf1a30Sjl	 nop
18425cf1a30Sjl
18525cf1a30Sjl	/* we branch to 4f but eventually we branch back here to finish up */
18625cf1a30Sjl1:
18725cf1a30Sjl	mov	%l6, %o5
18825cf1a30Sjl	/*
18925cf1a30Sjl	 * save some registers for debugging
19025cf1a30Sjl	 * l0 - SCF_REG_BASE
19125cf1a30Sjl	 * l1 - SCF_TD
19225cf1a30Sjl	 * l2 - SCF_TD + 8
19325cf1a30Sjl	 * l5 - DELAY
19425cf1a30Sjl	 */
19525cf1a30Sjl	add	%o0, SAVE_LOG, %o1
19625cf1a30Sjl	stx	%l0, [%o1+8*0]
19725cf1a30Sjl	stx	%l1, [%o1+8*1]
19825cf1a30Sjl	stx	%l2, [%o1+8*2]
19925cf1a30Sjl	stx	%l5, [%o1+8*3]
20025cf1a30Sjl
20125cf1a30Sjl	add	%o0, FMEM_ISSUED, %o1
20225cf1a30Sjl	st	%l7, [%o1]
20325cf1a30Sjl
20425cf1a30Sjl	/* Check for L2_CTRL_UGE_TRAP error */
20525cf1a30Sjl	mov	ASI_L2_CTRL_RW_ADDR, %l0
20625cf1a30Sjl	ldxa	[%l0]ASI_L2_CTRL, %l1
20725cf1a30Sjl	sethi	%hi(ASI_L2_CTRL_UGE_TRAP), %l2
20825cf1a30Sjl	btst	%l1, %l2
20925cf1a30Sjl	bz,pn	%xcc, 2f
21025cf1a30Sjl	 nop
211b307f191Sbm	set	EOPL_FMEM_HW_ERROR, %o4
21225cf1a30Sjl2:
21325cf1a30Sjl	/* restore all locals */
21425cf1a30Sjl	add	%o0, SAVE_LOCAL, %o1
21525cf1a30Sjl	ldx	[%o1+8*0], %l0
21625cf1a30Sjl	ldx	[%o1+8*1], %l1
21725cf1a30Sjl	ldx	[%o1+8*2], %l2
21825cf1a30Sjl	ldx	[%o1+8*3], %l3
21925cf1a30Sjl	ldx	[%o1+8*4], %l4
22025cf1a30Sjl	ldx	[%o1+8*5], %l5
22125cf1a30Sjl	ldx	[%o1+8*6], %l6
22225cf1a30Sjl	ldx	[%o1+8*7], %l7
22325cf1a30Sjl
22425cf1a30Sjl	/* turn on speculative mode */
22525cf1a30Sjl	ldxa	[%g0]ASI_MCNTL, %o1
22625cf1a30Sjl	set	1, %o2
22725cf1a30Sjl	sllx	%o2, MCNTL_SPECULATIVE_SHIFT, %o2
22825cf1a30Sjl	andn	%o1, %o2, %o1
22925cf1a30Sjl	ba	3f
23025cf1a30Sjl	 nop
23125cf1a30Sjl.align 32
23225cf1a30Sjl3:
23325cf1a30Sjl	stxa	%o1, [%g0]ASI_MCNTL
23425cf1a30Sjl	membar	#Sync
23525cf1a30Sjl	/* return error code here */
23625cf1a30Sjl	mov	%o4, %o0
23725cf1a30Sjl	retl
23825cf1a30Sjl	 wrpr	%g0, %o5, %pstate
23925cf1a30Sjl
24025cf1a30Sjl	/* clear L2_CTRL_UGE_TRAP error bit */
24125cf1a30Sjl4:
24225cf1a30Sjl	mov	ASI_L2_CTRL_RW_ADDR, %l0
24325cf1a30Sjl	ldxa	[%l0]ASI_L2_CTRL, %l1
24425cf1a30Sjl	sethi	%hi(ASI_L2_CTRL_UGE_TRAP), %l2
24525cf1a30Sjl	btst	%l1, %l2
24625cf1a30Sjl	bz,pn	%xcc, 5f
24725cf1a30Sjl	 nop
24825cf1a30Sjl	stxa	%l2, [%l0]ASI_L2_CTRL
24925cf1a30Sjl5:
25025cf1a30Sjl	/* set up the register locations and parameters */
25125cf1a30Sjl	ldx	[%o0 + SCF_REG_BASE], %l0
25225cf1a30Sjl	ldx	[%o0 + SCF_TD], %l1
25325cf1a30Sjl	ldx	[%o0 + SCF_TD+8], %l2
25425cf1a30Sjl	ldx	[%o0 + DELAY], %l5
25525cf1a30Sjl
2564fe85d41SJames Anderson	/* check if SCF is ONLINE */
2574fe85d41SJames Anderson	add	%l0, SCF_STATUS_EX, %o1
2584fe85d41SJames Anderson	lduwa	[%o1]ASI_IO, %o2
2594fe85d41SJames Anderson	sethi	%hi(SCF_STATUS_EX_ONLINE), %o3
2604fe85d41SJames Anderson	btst	%o2, %o3
2614fe85d41SJames Anderson	bne	%xcc, 6f
2624fe85d41SJames Anderson	 nop
2634fe85d41SJames Anderson	set	EOPL_FMEM_SCF_OFFLINE, %o4
2644fe85d41SJames Anderson	ba	1b
2654fe85d41SJames Anderson	 nop
2664fe85d41SJames Anderson
26725cf1a30Sjl	/* check if SCF is busy */
26825cf1a30Sjl	add	%l0, SCF_COMMAND, %o1
26925cf1a30Sjl	lduha	[%o1]ASI_IO, %o2
27025cf1a30Sjl	sethi	%hi(SCF_CMD_BUSY), %o3
27125cf1a30Sjl	btst	%o2, %o3
27225cf1a30Sjl	be	%xcc, 6f
27325cf1a30Sjl	 nop
274b307f191Sbm	set	EOPL_FMEM_SCF_BUSY, %o4
27525cf1a30Sjl	ba	1b
276b307f191Sbm	 nop
27725cf1a30Sjl
27825cf1a30Sjl	/* clear STATUS bit */
27925cf1a30Sjl6:
28025cf1a30Sjl	add	%l0, SCF_STATUS, %o1
28125cf1a30Sjl	lduha	[%o1]ASI_IO, %o2
28225cf1a30Sjl	sethi	%hi(SCF_STATUS_READY), %o3
28325cf1a30Sjl	btst	%o2, %o3
28425cf1a30Sjl	be	%xcc, 7f
28525cf1a30Sjl	 nop
28625cf1a30Sjl	stha	%o3, [%o1]ASI_IO
28725cf1a30Sjl
28825cf1a30Sjl	/* clear CMD_COMPLETE bit */
28925cf1a30Sjl7:
29025cf1a30Sjl	mov	SCF_STATUS_CMD_COMPLETE, %o3
29125cf1a30Sjl	btst	%o2, %o3
29225cf1a30Sjl	be,a	%xcc, 8f
29325cf1a30Sjl	 nop
29425cf1a30Sjl	stha	%o3, [%o1]ASI_IO
29525cf1a30Sjl8:
29625cf1a30Sjl	add	%l0, (SCF_TDATA+0xe), %o1
29725cf1a30Sjl	mov	%l2, %o4
29825cf1a30Sjl	mov	SCF_RETRY_CNT, %o5
29925cf1a30Sjl
30025cf1a30Sjl	sethi	%hi(0xffff), %l2
30125cf1a30Sjl	or	%l2, %lo(0xffff), %l2
30225cf1a30Sjl
30325cf1a30Sjl	and	%o4, %l2, %o3
30425cf1a30Sjl
30525cf1a30Sjl	/*
30625cf1a30Sjl	 * o1 points to SCFBASE.SCF_TDATA[0xe]
30725cf1a30Sjl	 * l0 points to SCFBASE
30825cf1a30Sjl	 * crticial->SCF_TD[0] = source board #
30925cf1a30Sjl	 * crticial->SCF_TD[1] = target board #
31025cf1a30Sjl	 * l1 = critical->SCF_TD[0 - 7]
31125cf1a30Sjl	 * l2 = 0xffff
31225cf1a30Sjl	 * o4 = critical->SCF_TD[8 - 15]
31325cf1a30Sjl	 * o3 = (*o4) & 0xffff
31425cf1a30Sjl
31525cf1a30Sjl	/*
31625cf1a30Sjl	 * Because there is no parity protection on the ebus
31725cf1a30Sjl	 * we read the data back after the write to verify
31825cf1a30Sjl	 * we write 2 bytes at a time.
31925cf1a30Sjl	 * If the data read is not the same as data written
320b307f191Sbm	 * we retry up to a limit of SCF_RETRY_CNT
32125cf1a30Sjl	 */
32225cf1a30Sjl9:
32325cf1a30Sjl	stha	%o3, [%o1]ASI_IO
32425cf1a30Sjl	lduha	[%o1]ASI_IO, %o2
32525cf1a30Sjl	sub	%o5, 1, %o5
326b307f191Sbm	brnz	%o5, 7f
327b307f191Sbm	 nop
328b307f191Sbm	set	EOPL_FMEM_RETRY_OUT, %o4
329b307f191Sbm	ba	1b
330b307f191Sbm	 nop
331b307f191Sbm7:
33225cf1a30Sjl	cmp	%o2, %o3
33325cf1a30Sjl	bne,a	9b
33425cf1a30Sjl	 nop
33525cf1a30Sjl
33625cf1a30Sjl	sub	%o1, %l0, %o2
33725cf1a30Sjl	cmp	%o2, (SCF_TDATA+0x8)
33825cf1a30Sjl	bne	%xcc, 2f
33925cf1a30Sjl	 srlx	%o4, 16, %o4
34025cf1a30Sjl	mov	%l1, %o4
34125cf1a30Sjl
34225cf1a30Sjl	/* if we have reach TDATA+8, we switch to l1 */
34325cf1a30Sjl	/* XXX: Why we need 2 loops??? */
34425cf1a30Sjl2:
34525cf1a30Sjl	sub	%o1, 2, %o1
34625cf1a30Sjl	mov	SCF_RETRY_CNT, %o5
34725cf1a30Sjl	and	%o4, %l2, %o3
34825cf1a30Sjl
34925cf1a30Sjl	sub	%o1, %l0, %o2
35025cf1a30Sjl	cmp	%o2, (SCF_TDATA)
35125cf1a30Sjl	bge,a	9b
35225cf1a30Sjl	 nop
35325cf1a30Sjl
35425cf1a30Sjl	/* if we reach TDATA, we are done */
35525cf1a30Sjl
35625cf1a30Sjl	/* read from SCF back to our buffer for debugging */
35725cf1a30Sjl	add	%l0, (SCF_TDATA), %o1
35825cf1a30Sjl	ldxa	[%o1]ASI_IO, %o2
35925cf1a30Sjl	stx	%o2, [%o0+SCF_TD]
36025cf1a30Sjl
36125cf1a30Sjl	add	%l0, (SCF_TDATA+8), %o1
36225cf1a30Sjl	ldxa	[%o1]ASI_IO, %o2
36325cf1a30Sjl	stx	%o2, [%o0+SCF_TD+8]
36425cf1a30Sjl
365b307f191Sbm	/* The following code conforms to the FMEM
366b307f191Sbm	   sequence (4) as described in the Columbus2
367b307f191Sbm	   logical spec section 4.6
368b307f191Sbm	*/
369b307f191Sbm
370b307f191Sbm	/* read from SCF SB INFO register */
371b307f191Sbm	sethi	%hi(SCF_SB_INFO_OFFSET), %o2
372b307f191Sbm	or	%o2, %lo(SCF_SB_INFO_OFFSET), %o2
373b307f191Sbm	add	%l0, %o2, %o1
374b307f191Sbm	lduba	[%o1]ASI_IO, %o2
375b307f191Sbm
376b307f191Sbm	/* If BUSY bit is set, abort */
377b307f191Sbm	or	%g0, (SCF_SB_INFO_BUSY), %o1
378b307f191Sbm	btst	%o1, %o2
379b307f191Sbm	set	EOPL_FMEM_SCF_BUSY, %o4
380b307f191Sbm	bne	1b
381b307f191Sbm	 nop
38225cf1a30Sjl
38325cf1a30Sjl	rd	STICK, %l1
38425cf1a30Sjl	add	%l5, %l1, %l5
38525cf1a30Sjl
38625cf1a30Sjl	/* Now tell SCF to do it */
38725cf1a30Sjl	add	%l0, SCF_COMMAND, %o1
38825cf1a30Sjl
38925cf1a30Sjl	/* 0x10A6 is the magic command */
39025cf1a30Sjl	sethi	%hi(0x10A6), %o2
39125cf1a30Sjl	or	%o2, %lo(0x10A6), %o2
39225cf1a30Sjl	stha	%o2, [%o1]ASI_IO
39325cf1a30Sjl
39425cf1a30Sjl	mov	1, %l7			! FMEM is issued
39525cf1a30Sjl
39625cf1a30Sjl	add	%l0, SCF_STATUS, %o1
39725cf1a30Sjl	sethi	%hi(SCF_STATUS_READY), %o2
39825cf1a30Sjl	mov	SCF_STATUS_CMD_COMPLETE, %o3
39925cf1a30Sjl
40025cf1a30Sjl	/* read STATUS_READY bit and clear it only if it is set */
40125cf1a30Sjl	/* XXX: this STATUS_READY checking seems meaningless */
40225cf1a30Sjl3:
40325cf1a30Sjl	lduha	[%o1]ASI_IO, %o4
40425cf1a30Sjl	btst	%o2, %o4
40525cf1a30Sjl	be	%xcc, 4f		! STATUS_READY is not set
40625cf1a30Sjl	 nop
40725cf1a30Sjl	stha	%o2, [%o1]ASI_IO	! Clear if the bit is set
40825cf1a30Sjl
40925cf1a30Sjl	/* check CMD_COMPLETE bit and clear */
41025cf1a30Sjl4:
41125cf1a30Sjl	btst	%o3, %o4
41225cf1a30Sjl	be	%xcc, 5f		! CMD_COMPLETE is not set
41325cf1a30Sjl	 nop
41425cf1a30Sjl	stha	%o3, [%o1]ASI_IO	! Now we are done and clear it
41525cf1a30Sjl	ba	%xcc, 6f
416b307f191Sbm	 mov	ESBD_NOERROR, %o4
41725cf1a30Sjl
41825cf1a30Sjl	/* timeout delay checking */
41925cf1a30Sjl5:
42025cf1a30Sjl	rd	STICK, %l2
42125cf1a30Sjl	cmp	%l5, %l2
42225cf1a30Sjl	bge	%xcc, 3b
42325cf1a30Sjl	 nop
424b307f191Sbm	set	EOPL_FMEM_TIMEOUT, %o4
42525cf1a30Sjl
42625cf1a30Sjl	/* we are done or timed out */
42725cf1a30Sjl6:
42825cf1a30Sjl	ba,a	1b
42925cf1a30Sjl	 nop
43025cf1a30Sjl	SET_SIZE(drmach_fmem_exec_script)
4319b0bb795SJohn Levon
43225cf1a30Sjl	ENTRY_NP(drmach_fmem_exec_script_end)
43325cf1a30Sjl	nop
43425cf1a30Sjl	SET_SIZE(drmach_fmem_exec_script_end)
43525cf1a30Sjl
43625cf1a30Sjl	ENTRY_NP(patch_inst)
43725cf1a30Sjl	ldx	[%o0], %o2
43825cf1a30Sjl	casx	[%o0], %o2, %o1
43925cf1a30Sjl	flush	%o0
44025cf1a30Sjl	membar #Sync
44125cf1a30Sjl	ldx	[%o0], %o2
44225cf1a30Sjl	retl
44325cf1a30Sjl	 mov	%o2, %o0
44425cf1a30Sjl	SET_SIZE(patch_inst)
44525cf1a30Sjl
44625cf1a30Sjl	ENTRY_NP(drmach_sys_trap)
44725cf1a30Sjl	mov	-1, %g4
44825cf1a30Sjl	set	sys_trap, %g5
44925cf1a30Sjl	jmp	%g5
45025cf1a30Sjl	 nop
45125cf1a30Sjl	SET_SIZE(drmach_sys_trap)
4529b0bb795SJohn Levon
45325cf1a30Sjl	ENTRY_NP(drmach_get_stick)
45425cf1a30Sjl	retl
45525cf1a30Sjl	rd	STICK, %o0
45625cf1a30Sjl	SET_SIZE(drmach_get_stick)
45725cf1a30Sjl
45825cf1a30Sjl	ENTRY_NP(drmach_flush)
45925cf1a30Sjl	mov	%o0, %o2
46025cf1a30Sjl0:
46125cf1a30Sjl	flush	%o2
46225cf1a30Sjl	sub	%o1, 8, %o1
46325cf1a30Sjl	brnz	%o1, 0b
46425cf1a30Sjl	 add	%o2, 8, %o2
46525cf1a30Sjl	retl
46625cf1a30Sjl	 nop
46725cf1a30Sjl	SET_SIZE(drmach_flush)
468