/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#if defined(lint)
#else /* lint */
#include "assym.h"
#endif /* lint */
#include <sys/asm_linkage.h>
#include <sys/machthread.h>
#include <sys/machcpuvar.h>
#ifdef TRAPTRACE
#include <sys/traptrace.h>
#endif /* TRAPTRACE */
#if defined(lint)
void
vec_interrupt(void)
{}
#else /* lint */
/*
* (TT 0x60, TL>0) Interrupt Vector Handler
* Globals are the Interrupt Globals.
*/
!
!
!
!
#ifndef _OPL
6:
#endif /* _OPL */
7:
!
!
!
!
#ifdef TRAPTRACE
#endif /* TRAPTRACE */
#ifdef SF_ERRATA_51
.align 32
#else
#endif /* SF_ERRATA_51 */
/* Never Reached */
0:
!
!
! be < MAXIVNUM) since setvecint_tl1 will do that for us.
!
! clear BUSY bit
!
stxa %g0, [%g0]ASI_INTR_RECEIVE_STATUS
membar #Sync
! setvecint_tl1 will do all the work, and finish with a retry
!
ba,pt %xcc, setvecint_tl1
mov %g5, %g1 ! setvecint_tl1 expects inum in %g1
/* Never Reached */
SET_SIZE(vec_interrupt)
!
! interrupt format
!
! Inputs:
! g1: value of ASI_INTR_RECEIVE_STATUS
! g5: word 0 of the interrupt data
! Register use:
! g2: dmv inum
! g3: scratch
! g4: pointer to dmv_dispatch_table
! g6: handler pointer from dispatch table
DGDEF(dmv_spurious_cnt)
.word 0
ENTRY_NP(dmv_vector)
srlx %g5, DMV_INUM_SHIFT, %g2
set DMV_INUM_MASK, %g3
and %g2, %g3, %g2 ! %g2 = inum
set dmv_totalints, %g3
ld [%g3], %g3
cmp %g2, %g3
bge,pn %xcc, 2f ! inum >= dmv_totalints
nop
set dmv_dispatch_table, %g3
ldn [%g3], %g4
brz,pn %g4, 2f
sll %g2, DMV_DISP_SHIFT, %g3 ! %g3 = inum*sizeof(struct dmv_disp)
add %g4, %g3, %g4 ! %g4 = &dmv_dispatch_table[inum]
#if (DMV_FUNC != 0) || (DMV_ARG != 8)
#error "DMV_FUNC or DMV_SIZE has changed"
#endif
ldda [%g4]ASI_NQUAD_LD, %g2 ! %g2=handler %g3=argument
mov %g3, %g1
brz,pn %g2, 2f
nop
! we have a handler, so call it
! On entry to the handler, the %g registers are set as follows:
!
! %g1 The argument (arg) passed to dmv_add_intr().
! %g2 Word 0 of the incoming mondo vector.
!
jmp %g2
mov %g5, %g2
! No handler was listed in the table, so just record it
! as an error condition and continue. There is a race
2:
set dmv_spurious_cnt, %g1
ld [%g1], %g2
inc %g2
ba,pt %xcc,3f
st %g2, [%g1]
! follows:
!
3:
#endif /* lint */
#if defined(lint)
void
vec_intr_spurious(void)
{}
#else /* lint */
.word 0
#ifdef TRAPTRACE
#endif /* TRAPTRACE */
!
! %g1 - sys_tl1_panic
!
/*
* Certain processors (OPL) need to explicitly
* clear the intr busy bit even though it is
* not visibly set (spurious intrs)
*/
#endif /* CLEAR_INTR_BUSYBIT_ON_SPURIOUS */
!
#endif /* lint */