* ========== Copyright Header Begin ==========================================
* Hypervisor Software File: intr.s
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
* - Do no alter or remove copyright notices
* - Redistribution and use of this software in source and binary forms, with
* or without modification, are permitted provided that the following
* - Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistribution in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of Sun Microsystems, Inc. or the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* This software is provided "AS IS," without a warranty of any kind.
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
* MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
* OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
* FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
* DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* You acknowledge that this software is not designed, licensed or
* intended for use in the design, construction, operation or maintenance of
* ========== Copyright Header End ============================================
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
.ident "@(#)intr.s 1.43 07/05/03 SMI"
#include <sys/asm_linkage.h>
* handles an incoming cpu_mondo x-call from another
* strand hosting a vcpu in the same domain as the current vcpu
* retry trapped instruction
* Update when we were called last
stx %g6, [%g1 + CPU_CMD_LASTPOKE]
* Wait for mailbox to not be busy
1: ldx [%g1 + CPU_COMMAND], %g6
cmp %g6, CPU_CMD_GUESTMONDO_READY
bne,pn %xcc, .cpu_mondo_return
mov CPU_MONDO_QUEUE_TAIL, %g2
ldx [%g1 + CPU_CPUQ_MASK], %g6
mov CPU_MONDO_QUEUE_HEAD, %g2
be,pn %xcc, .cpu_mondo_return ! queue is full
ldx [%g1 + CPU_CPUQ_BASE], %g6
! Simply return and drop mondo if Q was unconfigured from under us
brz %g6, .cpu_mondo_return
mov CPU_MONDO_QUEUE_TAIL, %g2
stxa %g5, [%g2]ASI_QUEUE ! new tail pointer
/* Fill in newly-allocated cpu mondo entry */
ldx [%g1 + CPU_CMD_ARG0], %g6
stxa %g6, [%g5]ASI_BLK_INIT_P
ldx [%g1 + CPU_CMD_ARG1], %g6
ldx [%g1 + CPU_CMD_ARG2], %g6
ldx [%g1 + CPU_CMD_ARG3], %g6
ldx [%g1 + CPU_CMD_ARG4], %g6
ldx [%g1 + CPU_CMD_ARG5], %g6
ldx [%g1 + CPU_CMD_ARG6], %g6
ldx [%g1 + CPU_CMD_ARG7], %g6
membar #Sync ! make sure stores visible
stx %g0, [%g1 + CPU_COMMAND] ! clear for next xcall
* %g7 + 4 = return address
* FIXME: This should probably arrive with a pointer to the
* vcpu the mondo is targeted at
ENTRY_NP(insert_device_mondo_r)
VCPU_STRUCT(%g1) /* FIXME ! */
ba send_dev_mondo ! tail call returns to caller
SET_SIZE(insert_device_mondo_r)
* %g7 + 4 = return address
ENTRY_NP(insert_device_mondo_p)
ba send_dev_mondo ! tail call returns to caller
PRINT("dev q unconfigured\r\n");
SET_SIZE(insert_device_mondo_p)
* %g2 = flag (0 = pointer to data, 1 = mondo)
* %g3 = data (depending on value of flag)
* %g7 + 4 = return address
add %g1, CPU_DEVQ_LOCK, %g4
SPINLOCK_ENTER(%g4, %g5, %g6)
ldx [ %g1 + CPU_DEVQ_BASE ], %g4
brz,a %g4, 4f ! Queue not configured exit!
ldx [ %g1 + CPU_DEVQ_SHDW_TAIL ], %g5
ldx [%g1 + CPU_DEVQ_MASK ], %g4
stx %g6, [ %g1 + CPU_DEVQ_SHDW_TAIL ]
ldx [ %g1 + CPU_DEVQ_BASE ], %g4
add %g5, %g4, %g5 ! pointer to stuff mondo
brz %g2, 1f ! data or pointer in %g3?
! Just update the local cpu's devq since it is the target.
* XXX Sanity test that new tail does not corrupt head of queue
set DEV_MONDO_QUEUE_TAIL, %g4
stxa %g6, [%g4] ASI_QUEUE
* Poke target to update DevQ
VCPU2STRAND_STRUCT(%g1, %g2)
ldub [%g2 + STRAND_ID], %g2
sllx %g2, INT_VEC_DIS_VCID_SHIFT, %g3
or %g3, VECINTR_VDEV, %g3
stxa %g3, [%g0]ASI_INTR_UDB_W
add %g1, CPU_DEVQ_LOCK, %g4
add %g1, CPU_DEVQ_LOCK, %g2
SPINLOCK_ENTER(%g2, %g3, %g4)
ldx [ %g1 + CPU_DEVQ_SHDW_TAIL], %g3
set DEV_MONDO_QUEUE_TAIL, %g4
stxa %g3, [ %g4 ] ASI_QUEUE
add %g1, CPU_DEVQ_LOCK, %g2
* dev_mondo - handle an incoming JBus mondo
* %g7 + 4 = return address
! XXX Check BUSY bit and ignore the dev mondo if it is not set
setx DEV_MONDO_INT, %g4, %g6
ldx [%g6 + DEV_MONDO_INT_ABUSY], %g4
btst DEV_MONDO_INT_ABUSY_BUSY, %g4
bz,pn %xcc, 2f ! Not BUSY .. just ignore
ldx [%g6 + DEV_MONDO_INT_DATA0], %g2 ! THREADID[5:0],INO[5:0]
ldx [%g6 + DEV_MONDO_INT_DATA1], %g3 ! IGN[5:0],ZERO[5:0]
stx %g0, [%g6 + DEV_MONDO_INT_ABUSY] ! Clear BUSY bit
! vINOs and what I/O bridge puts into DATA0 are
! the same therefore we don't need to translate
and %g2, NINOSPERDEV - 1 , %g4
srlx %g3, DEV_DEVINO_SHIFT, %g3
JMPL_VINO2DEVOP(%g2, DEVOPSVEC_MONDO_RECEIVE, %g1, %g6, 2f)
* We were interrupted for a x-call mondo for something.
* so we stash the state of the current vcpu and
* jump to the main handler/scheduler function
set CPU_LAUNCH_WITH_RETRY, %g3
ba,pt %xcc, handle_hvmondo