xref: /titanic_44/usr/src/uts/sparc/ml/fd_asm.s (revision a1b5e537933659371285214eae1db2603e6364b4)
17c478bd9Sstevel@tonic-gate/*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate * with the License.
87c478bd9Sstevel@tonic-gate *
97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate * and limitations under the License.
137c478bd9Sstevel@tonic-gate *
147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate *
207c478bd9Sstevel@tonic-gate * CDDL HEADER END
217c478bd9Sstevel@tonic-gate */
227c478bd9Sstevel@tonic-gate/*
23*a1b5e537Sbmc * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*a1b5e537Sbmc * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate */
267c478bd9Sstevel@tonic-gate
277c478bd9Sstevel@tonic-gate#ident	"%Z%%M%	%I%	%E% SMI"
287c478bd9Sstevel@tonic-gate
297c478bd9Sstevel@tonic-gate/*
307c478bd9Sstevel@tonic-gate * This file contains no entry points which can be called directly from
317c478bd9Sstevel@tonic-gate * C and hence is of no interest to lint. However, we want to avoid the
327c478bd9Sstevel@tonic-gate * dreaded "Empty translation unit"  warning.
337c478bd9Sstevel@tonic-gate */
347c478bd9Sstevel@tonic-gate
357c478bd9Sstevel@tonic-gate#if defined(lint)
367c478bd9Sstevel@tonic-gate#include <sys/types.h>
377c478bd9Sstevel@tonic-gate
387c478bd9Sstevel@tonic-gate/*ARGSUSED*/
397c478bd9Sstevel@tonic-gateu_int
407c478bd9Sstevel@tonic-gatefd_intr(caddr_t arg)
417c478bd9Sstevel@tonic-gate{
427c478bd9Sstevel@tonic-gate	return (0);
437c478bd9Sstevel@tonic-gate}
447c478bd9Sstevel@tonic-gate
457c478bd9Sstevel@tonic-gate#else	/* lint */
467c478bd9Sstevel@tonic-gate
477c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h>
487c478bd9Sstevel@tonic-gate#include <sys/fdreg.h>
497c478bd9Sstevel@tonic-gate#include <sys/fdvar.h>
507c478bd9Sstevel@tonic-gate#include "fd_assym.h"
517c478bd9Sstevel@tonic-gate
527c478bd9Sstevel@tonic-gate/*
537c478bd9Sstevel@tonic-gate * Since this is part of a Sparc "generic" module, it may be loaded during
547c478bd9Sstevel@tonic-gate * reconfigure time on systems that do not support the fast interrupt
557c478bd9Sstevel@tonic-gate * handler.  On these machines the symbol "impl_setintreg_on" will be
567c478bd9Sstevel@tonic-gate * undefined but we don't want to cause error messages when we load.
577c478bd9Sstevel@tonic-gate */
587c478bd9Sstevel@tonic-gate	.weak	impl_setintreg_on
597c478bd9Sstevel@tonic-gate	.type	impl_setintreg_on, #function
607c478bd9Sstevel@tonic-gate	.weak	fd_softintr_cookie
617c478bd9Sstevel@tonic-gate	.type	fd_softintr_cookie, #object
627c478bd9Sstevel@tonic-gate
637c478bd9Sstevel@tonic-gate#define	Tmp2	%l4	/* temp register prior to dispatch to right opmode */
647c478bd9Sstevel@tonic-gate#define	Reg	%l4	/* pointer to the chip's registers */
657c478bd9Sstevel@tonic-gate#define	Fdc	%l3	/* pointer to fdctlr structure */
667c478bd9Sstevel@tonic-gate#define	Adr	%l5	/* data address pointer */
677c478bd9Sstevel@tonic-gate#define	Len	%l6	/* data length counter */
687c478bd9Sstevel@tonic-gate#define	Tmp	%l7	/* general scratch */
697c478bd9Sstevel@tonic-gate#define	TRIGGER	0x33
707c478bd9Sstevel@tonic-gate	ENTRY(fd_intr)		! fd standard interrupt handler
717c478bd9Sstevel@tonic-gate	save	%sp, -SA(MINFRAME), %sp
727c478bd9Sstevel@tonic-gate	!
737c478bd9Sstevel@tonic-gate	! Traverse the list of controllers until we find the first
747c478bd9Sstevel@tonic-gate	! controller expecting an interrupt. Unfortunately, the
757c478bd9Sstevel@tonic-gate	! 82072 floppy controller really doesn't have a way to tell
767c478bd9Sstevel@tonic-gate	! you that it is interrupting.
777c478bd9Sstevel@tonic-gate	!
787c478bd9Sstevel@tonic-gate	set	fdctlrs, Fdc		! load list of controllers
797c478bd9Sstevel@tonic-gate	ldn	[Fdc], Fdc		! get the first in the list...
807c478bd9Sstevel@tonic-gate1:	tst	Fdc			! do we have any more to check
817c478bd9Sstevel@tonic-gate	bz	.panic			! Nothing to service. Panic
827c478bd9Sstevel@tonic-gate	nop
837c478bd9Sstevel@tonic-gate
847c478bd9Sstevel@tonic-gate3:	ldub	[Fdc + FD_OPMODE], Tmp2	! load opmode into Tmp2
857c478bd9Sstevel@tonic-gate	and	Tmp2, 0x3, Tmp2		! opmode must be 1, 2, or 3
867c478bd9Sstevel@tonic-gate	tst	Tmp2			! non-zero?
877c478bd9Sstevel@tonic-gate	bnz	.mutex_enter		! yes!
887c478bd9Sstevel@tonic-gate	nop
897c478bd9Sstevel@tonic-gate	ldn	[Fdc + FD_NEXT], Tmp	! Try next ctlr...
907c478bd9Sstevel@tonic-gate	tst	Tmp
917c478bd9Sstevel@tonic-gate	bnz,a	1b
927c478bd9Sstevel@tonic-gate	mov	Tmp, Fdc
937c478bd9Sstevel@tonic-gate					! no more controllers
947c478bd9Sstevel@tonic-gate	mov	0x2, Tmp2		! must be spurious or "ready" int
957c478bd9Sstevel@tonic-gate.mutex_enter:
967c478bd9Sstevel@tonic-gate	!
977c478bd9Sstevel@tonic-gate	! grab high level mutex for this controller
987c478bd9Sstevel@tonic-gate	!
997c478bd9Sstevel@tonic-gate	sethi	%hi(asm_mutex_spin_enter), %l7
1007c478bd9Sstevel@tonic-gate	jmpl	%l7 + %lo(asm_mutex_spin_enter), %l7
1017c478bd9Sstevel@tonic-gate	add	Fdc, FD_HILOCK, %l6
1027c478bd9Sstevel@tonic-gate	!
1037c478bd9Sstevel@tonic-gate	! dispatch to correct handler
1047c478bd9Sstevel@tonic-gate	!
1057c478bd9Sstevel@tonic-gate	cmp	Tmp2, 3			!case 3: results ?
1067c478bd9Sstevel@tonic-gate	be,a	.opmode3		! yes...
1077c478bd9Sstevel@tonic-gate	ldn	[Fdc + FD_REG], Reg	! load pointer to h/w registers
1087c478bd9Sstevel@tonic-gate	cmp	Tmp2, 2			!case 2: seek/recalibrate ?
1097c478bd9Sstevel@tonic-gate	be	.opmode2		! yes..
1107c478bd9Sstevel@tonic-gate	ldn	[Fdc + FD_REG], Reg	! load pointer to h/w registers
1117c478bd9Sstevel@tonic-gate	!
1127c478bd9Sstevel@tonic-gate	! opmode 1:
1137c478bd9Sstevel@tonic-gate	! read/write/format data-xfer case - they have a result phase
1147c478bd9Sstevel@tonic-gate	!
1157c478bd9Sstevel@tonic-gate.opmode1:
1167c478bd9Sstevel@tonic-gate	ld	[Fdc + FD_RLEN], Len
1177c478bd9Sstevel@tonic-gate	!
1187c478bd9Sstevel@tonic-gate	! XXX- test for null raddr
1197c478bd9Sstevel@tonic-gate	!
1207c478bd9Sstevel@tonic-gate	ldn	[Fdc + FD_RADDR], Adr
1217c478bd9Sstevel@tonic-gate
1227c478bd9Sstevel@tonic-gate	!
1237c478bd9Sstevel@tonic-gate	! while the fifo ready bit set, then data/status available
1247c478bd9Sstevel@tonic-gate	!
1257c478bd9Sstevel@tonic-gate1:	ldub	[Reg], Tmp		! get csr
1267c478bd9Sstevel@tonic-gate	andcc	Tmp, RQM, %g0		!
1277c478bd9Sstevel@tonic-gate	be	4f			! branch if bit clear
1287c478bd9Sstevel@tonic-gate	andcc	Tmp, NDM, %g0		! NDM set means data
1297c478bd9Sstevel@tonic-gate	be	7f			! if not set, it is status time
1307c478bd9Sstevel@tonic-gate	andcc	Tmp, DIO, %g0		! check for input vs. output data
1317c478bd9Sstevel@tonic-gate	be	2f			!
1327c478bd9Sstevel@tonic-gate	sub	Len, 0x1, Len		! predecrement length...
1337c478bd9Sstevel@tonic-gate	ldub	[Reg + 0x1], Tmp	! DIO set, *addr = *fifo
1347c478bd9Sstevel@tonic-gate	b	3f			!
1357c478bd9Sstevel@tonic-gate	stb	Tmp, [Adr]		!
1367c478bd9Sstevel@tonic-gate2:	ldsb	[Adr], Tmp		! *fifo = *addr
1377c478bd9Sstevel@tonic-gate	stb	Tmp, [Reg + 0x1]	!
1387c478bd9Sstevel@tonic-gate3:	tst	Len			! if (len == 0) send TC
1397c478bd9Sstevel@tonic-gate	bne	1b			! branch if not....
1407c478bd9Sstevel@tonic-gate	add	Adr, 0x1, Adr		!
1417c478bd9Sstevel@tonic-gate	b	6f			!
1427c478bd9Sstevel@tonic-gate	.empty				!
1437c478bd9Sstevel@tonic-gate	!
1447c478bd9Sstevel@tonic-gate	! save updated len, addr
1457c478bd9Sstevel@tonic-gate	!
1467c478bd9Sstevel@tonic-gate4:	st	Len, [Fdc + FD_RLEN]
1477c478bd9Sstevel@tonic-gate	b	.out			! not done yet, return
1487c478bd9Sstevel@tonic-gate	stn	Adr, [Fdc + FD_RADDR]
1497c478bd9Sstevel@tonic-gate	!
1507c478bd9Sstevel@tonic-gate	! END OF TRANSFER - if read/write, toggle the TC
1517c478bd9Sstevel@tonic-gate	! bit in AUXIO_REG then save status and set state = 3.
1527c478bd9Sstevel@tonic-gate	!
1537c478bd9Sstevel@tonic-gate5:
1547c478bd9Sstevel@tonic-gate	!
1557c478bd9Sstevel@tonic-gate	! Stash len and addr before they get lost
1567c478bd9Sstevel@tonic-gate	!
1577c478bd9Sstevel@tonic-gate	st	Len, [Fdc + FD_RLEN]
1587c478bd9Sstevel@tonic-gate6:	stn	Adr, [Fdc + FD_RADDR]
1597c478bd9Sstevel@tonic-gate	!
1607c478bd9Sstevel@tonic-gate	! Begin TC delay...
1617c478bd9Sstevel@tonic-gate	! Old comment:
1627c478bd9Sstevel@tonic-gate	!	five nops provide 100ns of delay at 10MIPS to ensure
1637c478bd9Sstevel@tonic-gate	!	TC is wide enough at slowest possible floppy clock
1647c478bd9Sstevel@tonic-gate	!	(500ns @ 250Kbps).
1657c478bd9Sstevel@tonic-gate	!
1667c478bd9Sstevel@tonic-gate	! I gather this mean that we have to give 100ns delay for TC.
1677c478bd9Sstevel@tonic-gate	!
1687c478bd9Sstevel@tonic-gate	! At 100 Mips, that would be 1 * 10 (10) nops.
1697c478bd9Sstevel@tonic-gate	!
1707c478bd9Sstevel@tonic-gate
1717c478bd9Sstevel@tonic-gate	ldn	[Fdc + FD_AUXIOVA], Adr
1727c478bd9Sstevel@tonic-gate	ldub	[Fdc + FD_AUXIODATA], Tmp2
1737c478bd9Sstevel@tonic-gate	ldub	[Adr], Tmp
1747c478bd9Sstevel@tonic-gate	or	Tmp, Tmp2, Tmp
1757c478bd9Sstevel@tonic-gate	stb	Tmp, [Adr]
1767c478bd9Sstevel@tonic-gate	nop; nop; nop; nop; nop; nop; nop; nop; nop; nop	! 10 nops
1777c478bd9Sstevel@tonic-gate	!
1787c478bd9Sstevel@tonic-gate	! End TC delay...now clear the TC bit
1797c478bd9Sstevel@tonic-gate	!
1807c478bd9Sstevel@tonic-gate	ldub	[Fdc + FD_AUXIODATA2], Tmp2
1817c478bd9Sstevel@tonic-gate	andn	Tmp, Tmp2, Tmp
1827c478bd9Sstevel@tonic-gate	stb	Tmp, [Adr]
1837c478bd9Sstevel@tonic-gate
1847c478bd9Sstevel@tonic-gate	!
1857c478bd9Sstevel@tonic-gate	! set opmode to 3 to indicate going into status mode
1867c478bd9Sstevel@tonic-gate	!
1877c478bd9Sstevel@tonic-gate	mov	3, Tmp
1887c478bd9Sstevel@tonic-gate	b	.out
1897c478bd9Sstevel@tonic-gate	stb	Tmp, [Fdc + FD_OPMODE]
1907c478bd9Sstevel@tonic-gate	!
1917c478bd9Sstevel@tonic-gate	! error status state: save old pointers, go direct to result snarfing
1927c478bd9Sstevel@tonic-gate	!
1937c478bd9Sstevel@tonic-gate7:	st	Len, [Fdc + FD_RLEN]
1947c478bd9Sstevel@tonic-gate	stn	Adr, [Fdc + FD_RADDR]
1957c478bd9Sstevel@tonic-gate	mov	0x3, Tmp
1967c478bd9Sstevel@tonic-gate	b	.opmode3
1977c478bd9Sstevel@tonic-gate	stb	Tmp, [Fdc + FD_OPMODE]
1987c478bd9Sstevel@tonic-gate	!
1997c478bd9Sstevel@tonic-gate	! opmode 2:
2007c478bd9Sstevel@tonic-gate	! recalibrate/seek - no result phase, must do sense interrupt status.
2017c478bd9Sstevel@tonic-gate	!
2027c478bd9Sstevel@tonic-gate.opmode2:
2037c478bd9Sstevel@tonic-gate	ldub	[Reg], Tmp			! Tmp = *csr
2047c478bd9Sstevel@tonic-gate1:	andcc	Tmp, CB, %g0			! is CB set?
2057c478bd9Sstevel@tonic-gate	bne	1b				! yes, keep waiting
2067c478bd9Sstevel@tonic-gate	ldub	[Reg], Tmp			!! Tmp = *csr
2077c478bd9Sstevel@tonic-gate	!
2087c478bd9Sstevel@tonic-gate	! wait!!! should we check rqm first???  ABSOLUTELY YES!!!!
2097c478bd9Sstevel@tonic-gate	!
2107c478bd9Sstevel@tonic-gate1:	andcc	Tmp, RQM, %g0		!
2117c478bd9Sstevel@tonic-gate	be,a	1b			! branch if bit clear
2127c478bd9Sstevel@tonic-gate	ldub	[Reg], Tmp		! busy wait until RQM set
2137c478bd9Sstevel@tonic-gate	mov	SNSISTAT, Tmp		! cmd for SENSE_INTERRUPT_STATUS
2147c478bd9Sstevel@tonic-gate	stb	Tmp, [Reg + 0x1]
2157c478bd9Sstevel@tonic-gate	!
2167c478bd9Sstevel@tonic-gate	! NOTE: we ignore DIO here, assume it is set before RQM!
2177c478bd9Sstevel@tonic-gate	!
2187c478bd9Sstevel@tonic-gate	ldub	[Reg], Tmp			! busy wait until RQM set
2197c478bd9Sstevel@tonic-gate1:	andcc	Tmp, RQM, Tmp
2207c478bd9Sstevel@tonic-gate	be,a	1b				! branch if bit clear
2217c478bd9Sstevel@tonic-gate	ldub	[Reg], Tmp			! busy wait until RQM set
2227c478bd9Sstevel@tonic-gate	!
2237c478bd9Sstevel@tonic-gate	! fdc->c_csb.csb_rslt[0] = *fifo;
2247c478bd9Sstevel@tonic-gate	!
2257c478bd9Sstevel@tonic-gate	ldub	[Reg + 0x1], Tmp
2267c478bd9Sstevel@tonic-gate	stb	Tmp, [Fdc + FD_RSLT]
2277c478bd9Sstevel@tonic-gate	ldub	[Reg], Tmp			! busy wait until RQM set
2287c478bd9Sstevel@tonic-gate1:	andcc	Tmp, RQM, Tmp
2297c478bd9Sstevel@tonic-gate	be,a	1b				! branch if bit clear
2307c478bd9Sstevel@tonic-gate	ldub	[Reg], Tmp			! busy wait until RQM set
2317c478bd9Sstevel@tonic-gate	!
2327c478bd9Sstevel@tonic-gate	! fdc->c_csb.csb_rslt[1] = *fifo;
2337c478bd9Sstevel@tonic-gate	!
2347c478bd9Sstevel@tonic-gate	ldub	[Reg + 0x1], Tmp
2357c478bd9Sstevel@tonic-gate	b	.notify
2367c478bd9Sstevel@tonic-gate	stb	Tmp, [Fdc + FD_RSLT + 1]
2377c478bd9Sstevel@tonic-gate	!
2387c478bd9Sstevel@tonic-gate	! case 3: result mode
2397c478bd9Sstevel@tonic-gate	! We are in result mode make sure all status bytes are read out
2407c478bd9Sstevel@tonic-gate	!
2417c478bd9Sstevel@tonic-gate	! We have to have *both* RQM and DIO set.
2427c478bd9Sstevel@tonic-gate	!
2437c478bd9Sstevel@tonic-gate.opmode3:
2447c478bd9Sstevel@tonic-gate	add	Fdc, FD_RSLT, Adr		! load address of csb->csb_rslt
2457c478bd9Sstevel@tonic-gate	add	Adr, 10, Len			! put an upper bound on it..
2467c478bd9Sstevel@tonic-gate	ldub	[Reg], Tmp			!
2477c478bd9Sstevel@tonic-gate1:	andcc	Tmp, CB, %g0			! is CB set?
2487c478bd9Sstevel@tonic-gate	be	.notify				! no, jump around, must be done
2497c478bd9Sstevel@tonic-gate	andcc	Tmp, RQM, %g0			! check for RQM in delay slot
2507c478bd9Sstevel@tonic-gate	be,a	1b				! No RQM, go back
2517c478bd9Sstevel@tonic-gate	ldub	[Reg], Tmp			! and load control reg in delay
2527c478bd9Sstevel@tonic-gate	andcc	Tmp, DIO, %g0			! DIO set?
2537c478bd9Sstevel@tonic-gate	be,a	1b				! No DIO, go back
2547c478bd9Sstevel@tonic-gate	ldub	[Reg], Tmp			! and load control reg in delay
2557c478bd9Sstevel@tonic-gate	!
2567c478bd9Sstevel@tonic-gate	! CB && DIO && RQM all true.
2577c478bd9Sstevel@tonic-gate	! Time to get a byte.
2587c478bd9Sstevel@tonic-gate	!
2597c478bd9Sstevel@tonic-gate	ldub	[Reg + 0x1], Tmp		! *fifo into Tmp
2607c478bd9Sstevel@tonic-gate	cmp	Adr, Len			! already at our limit?
2617c478bd9Sstevel@tonic-gate	bge,a	1b				! Yes, go back..
2627c478bd9Sstevel@tonic-gate	ldub	[Reg], Tmp			! and load control reg in delay
2637c478bd9Sstevel@tonic-gate	stb	Tmp, [Adr]			! store new byte
2647c478bd9Sstevel@tonic-gate	add	Adr, 1, Adr			! increment address
2657c478bd9Sstevel@tonic-gate	b	1b				! and pop back to the top
2667c478bd9Sstevel@tonic-gate	ldub	[Reg], Tmp			! and load control reg in delay
2677c478bd9Sstevel@tonic-gate
2687c478bd9Sstevel@tonic-gate	!
2697c478bd9Sstevel@tonic-gate	! schedule 2nd stage interrupt
2707c478bd9Sstevel@tonic-gate	!
2717c478bd9Sstevel@tonic-gate.notify:
2727c478bd9Sstevel@tonic-gate	!
2737c478bd9Sstevel@tonic-gate	! if fast traps are enabled, use the platform dependent
2747c478bd9Sstevel@tonic-gate	! impl_setintreg_on function.
2757c478bd9Sstevel@tonic-gate	!
2767c478bd9Sstevel@tonic-gate	ldub    [Fdc + FD_FASTTRAP], Tmp
2777c478bd9Sstevel@tonic-gate	tst     Tmp
2787c478bd9Sstevel@tonic-gate	bnz	.fast
2797c478bd9Sstevel@tonic-gate	nop
2807c478bd9Sstevel@tonic-gate
2817c478bd9Sstevel@tonic-gate	!
2827c478bd9Sstevel@tonic-gate	! fast traps are not in use.  Do not schedule the soft interrupt
2837c478bd9Sstevel@tonic-gate	! at this time.  Wait to trigger it at the end of the handler
2847c478bd9Sstevel@tonic-gate	! when the mutexes have been released
2857c478bd9Sstevel@tonic-gate	!
2867c478bd9Sstevel@tonic-gate	mov   	TRIGGER, Tmp2
2877c478bd9Sstevel@tonic-gate	b	.out
2887c478bd9Sstevel@tonic-gate	nop
2897c478bd9Sstevel@tonic-gate
2907c478bd9Sstevel@tonic-gate	!
2917c478bd9Sstevel@tonic-gate	! fast traps are enabled.  Schedule the soft interrupt.
2927c478bd9Sstevel@tonic-gate	! impl_setintreg uses %l4-%l7
2937c478bd9Sstevel@tonic-gate	!
2947c478bd9Sstevel@tonic-gate.fast:	sethi   %hi(fd_softintr_cookie), %l6
2957c478bd9Sstevel@tonic-gate	sethi	%hi(impl_setintreg_on), %l7
2967c478bd9Sstevel@tonic-gate	jmpl	%l7 + %lo(impl_setintreg_on), %l7
2977c478bd9Sstevel@tonic-gate	ld      [%l6 + %lo(fd_softintr_cookie)], %l6
2987c478bd9Sstevel@tonic-gate	!
2997c478bd9Sstevel@tonic-gate	! set new opmode to 4
3007c478bd9Sstevel@tonic-gate	!
3017c478bd9Sstevel@tonic-gate	mov	0x4, Tmp
3027c478bd9Sstevel@tonic-gate	stb	Tmp, [Fdc + FD_OPMODE]
3037c478bd9Sstevel@tonic-gate
3047c478bd9Sstevel@tonic-gate	!
3057c478bd9Sstevel@tonic-gate	! and fall through to exit
3067c478bd9Sstevel@tonic-gate	!
3077c478bd9Sstevel@tonic-gate.out:
3087c478bd9Sstevel@tonic-gate	!
3097c478bd9Sstevel@tonic-gate	! update high level interrupt counter...
3107c478bd9Sstevel@tonic-gate	!
3117c478bd9Sstevel@tonic-gate	ldn	[Fdc + FD_HIINTCT], Adr
3127c478bd9Sstevel@tonic-gate	tst	Adr
3137c478bd9Sstevel@tonic-gate	be,a	1f
3147c478bd9Sstevel@tonic-gate	nop
3157c478bd9Sstevel@tonic-gate	ld	[Adr], Tmp
3167c478bd9Sstevel@tonic-gate	inc	Tmp
3177c478bd9Sstevel@tonic-gate	st	Tmp, [Adr]
3187c478bd9Sstevel@tonic-gate1:
3197c478bd9Sstevel@tonic-gate	!
3207c478bd9Sstevel@tonic-gate	! Release mutex
3217c478bd9Sstevel@tonic-gate	!
3227c478bd9Sstevel@tonic-gate	sethi	%hi(asm_mutex_spin_exit), %l7
3237c478bd9Sstevel@tonic-gate	jmpl	%l7 + %lo(asm_mutex_spin_exit), %l7
3247c478bd9Sstevel@tonic-gate	add	Fdc, FD_HILOCK, %l6
3257c478bd9Sstevel@tonic-gate
3267c478bd9Sstevel@tonic-gate	!
3277c478bd9Sstevel@tonic-gate	! schedule the soft interrupt if needed
3287c478bd9Sstevel@tonic-gate	!
3297c478bd9Sstevel@tonic-gate	cmp	Tmp2, TRIGGER
3307c478bd9Sstevel@tonic-gate	bne	.end
3317c478bd9Sstevel@tonic-gate	nop
3327c478bd9Sstevel@tonic-gate
3337c478bd9Sstevel@tonic-gate   	!
3347c478bd9Sstevel@tonic-gate	! set new opmode to 4
3357c478bd9Sstevel@tonic-gate        !
3367c478bd9Sstevel@tonic-gate	mov     0x4, Tmp
3377c478bd9Sstevel@tonic-gate        stb     Tmp, [Fdc + FD_OPMODE]
3387c478bd9Sstevel@tonic-gate
3397c478bd9Sstevel@tonic-gate	! invoke ddi_trigger_softintr.  load
3407c478bd9Sstevel@tonic-gate	! softid parameter in the delay slot
3417c478bd9Sstevel@tonic-gate	!
3427c478bd9Sstevel@tonic-gate	call	ddi_trigger_softintr
3437c478bd9Sstevel@tonic-gate	ldn	[Fdc + FD_SOFTID], %o0
3447c478bd9Sstevel@tonic-gate
3457c478bd9Sstevel@tonic-gate.end:	mov	1, %i0
3467c478bd9Sstevel@tonic-gate	ret
3477c478bd9Sstevel@tonic-gate	restore
3487c478bd9Sstevel@tonic-gate	SET_SIZE(fd_intr)
3497c478bd9Sstevel@tonic-gate
3507c478bd9Sstevel@tonic-gate.panic:
3517c478bd9Sstevel@tonic-gate        ! invoke a kernel panic
3527c478bd9Sstevel@tonic-gate        sethi   %hi(panic_msg), %o1
3537c478bd9Sstevel@tonic-gate        ldn    [%o1 + %lo(panic_msg)], %o1
3547c478bd9Sstevel@tonic-gate        mov     3, %o0
3557c478bd9Sstevel@tonic-gate        call    cmn_err
3567c478bd9Sstevel@tonic-gate	nop
3577c478bd9Sstevel@tonic-gate
3587c478bd9Sstevel@tonic-gate
3597c478bd9Sstevel@tonic-gate#endif  /* lint */
360