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 5*b0fc0e77Sgovinda * Common Development and Distribution License (the "License"). 6*b0fc0e77Sgovinda * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate/* 22*b0fc0e77Sgovinda * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate#pragma ident "%Z%%M% %I% %E% SMI" 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate/* 297c478bd9Sstevel@tonic-gate * This file contains the low-level DMV interrupt 307c478bd9Sstevel@tonic-gate * handler for IDN cross-domain interrupts. 317c478bd9Sstevel@tonic-gate */ 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate#if defined(lint) 347c478bd9Sstevel@tonic-gate#include <sys/types.h> 357c478bd9Sstevel@tonic-gate#endif /* lint */ 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h> 387c478bd9Sstevel@tonic-gate#include <sys/machasi.h> 397c478bd9Sstevel@tonic-gate#include <sys/privregs.h> 407c478bd9Sstevel@tonic-gate#include <sys/intreg.h> 417c478bd9Sstevel@tonic-gate#include <sys/machthread.h> 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate#include <sys/idn.h> 447c478bd9Sstevel@tonic-gate 457c478bd9Sstevel@tonic-gate#if !defined(lint) 467c478bd9Sstevel@tonic-gate#include "idn_offsets.h" 477c478bd9Sstevel@tonic-gate#endif /* !lint */ 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate#define IDN_MONDO 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate/* 527c478bd9Sstevel@tonic-gate * The IDN_DMV_CPU_SHIFT is based on the sizeof (idn_dmv_cpu_t) 537c478bd9Sstevel@tonic-gate * which must be a power of 2 to optimize calculating our 547c478bd9Sstevel@tonic-gate * entry into idn_dmv_cpu[]. 557c478bd9Sstevel@tonic-gate */ 567c478bd9Sstevel@tonic-gate#define IDN_DMV_CPU_SHIFT 4 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate/* 597c478bd9Sstevel@tonic-gate *-------------------------------------------------------- 607c478bd9Sstevel@tonic-gate */ 617c478bd9Sstevel@tonic-gate#if defined(lint) 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate/* 647c478bd9Sstevel@tonic-gate * Would be nice to use init_mondo, but unforunately 657c478bd9Sstevel@tonic-gate * it assumes the first arg is 32-bits. 667c478bd9Sstevel@tonic-gate */ 677c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 687c478bd9Sstevel@tonic-gatevoid 697c478bd9Sstevel@tonic-gateidnxf_init_mondo(uint64_t arg0, uint64_t arg1, uint64_t arg2) 707c478bd9Sstevel@tonic-gate{} 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate#else /* lint */ 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate .global _idn_dispatch_status_busy 757c478bd9Sstevel@tonic-gate_idn_dispatch_status_busy: 767c478bd9Sstevel@tonic-gate .asciz "ASI_INTR_DISPATCH_STATUS error: busy" 777c478bd9Sstevel@tonic-gate .align 4 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate ENTRY_NP(idnxf_init_mondo) 807c478bd9Sstevel@tonic-gate#ifdef DEBUG 817c478bd9Sstevel@tonic-gate ! 827c478bd9Sstevel@tonic-gate ! IDSR should not be busy at the moment - borrowed from init_mondo 837c478bd9Sstevel@tonic-gate ! 847c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_INTR_DISPATCH_STATUS, %g1 857c478bd9Sstevel@tonic-gate btst IDSR_BUSY, %g1 867c478bd9Sstevel@tonic-gate bz,pt %xcc, 1f 877c478bd9Sstevel@tonic-gate mov ASI_INTR_DISPATCH, %asi 887c478bd9Sstevel@tonic-gate sethi %hi(_idn_dispatch_status_busy), %o0 897c478bd9Sstevel@tonic-gate call panic 907c478bd9Sstevel@tonic-gate or %o0, %lo(_idn_dispatch_status_busy), %o0 917c478bd9Sstevel@tonic-gate#endif /* DEBUG */ 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate mov ASI_INTR_DISPATCH, %asi 947c478bd9Sstevel@tonic-gate1: 957c478bd9Sstevel@tonic-gate stxa %o0, [IDDR_0]%asi ! dmv_word0 967c478bd9Sstevel@tonic-gate stxa %o1, [IDDR_1]%asi ! dmv_word1 977c478bd9Sstevel@tonic-gate stxa %o2, [IDDR_2]%asi ! dmv_word2 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate retl 1007c478bd9Sstevel@tonic-gate membar #Sync 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate SET_SIZE(idnxf_init_mondo) 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate#endif /* lint */ 1057c478bd9Sstevel@tonic-gate/* 1067c478bd9Sstevel@tonic-gate *-------------------------------------------------------- 1077c478bd9Sstevel@tonic-gate */ 1087c478bd9Sstevel@tonic-gate#if defined(lint) 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate/* 1117c478bd9Sstevel@tonic-gate * Unfortunately, send_mondo is rather picky about getting 1127c478bd9Sstevel@tonic-gate * a result from the cpu it sends an interrupt to. If it 1137c478bd9Sstevel@tonic-gate * doesn't get a result within a specific timeframe it 1147c478bd9Sstevel@tonic-gate * will panic! For IDN that's not cool since a cpu hungup 1157c478bd9Sstevel@tonic-gate * in one could ultimately result in the demise of a cpu 1167c478bd9Sstevel@tonic-gate * in another domain. Instead of getting our panties in 1177c478bd9Sstevel@tonic-gate * a bind, we simply bail out. 1187c478bd9Sstevel@tonic-gate */ 1197c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 1207c478bd9Sstevel@tonic-gateint 1217c478bd9Sstevel@tonic-gateidnxf_send_mondo(int upaid) 1227c478bd9Sstevel@tonic-gate{ return (0); } 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate#else /* lint */ 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate .seg ".data" 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate .global _idn_send_mondo_failure 1297c478bd9Sstevel@tonic-gate_idn_send_mondo_failure: 1307c478bd9Sstevel@tonic-gate .word 0 1317c478bd9Sstevel@tonic-gate 1327c478bd9Sstevel@tonic-gate .seg ".text" 1337c478bd9Sstevel@tonic-gate ENTRY(idnxf_send_mondo) 1347c478bd9Sstevel@tonic-gate ! 1357c478bd9Sstevel@tonic-gate ! NOTE: 1367c478bd9Sstevel@tonic-gate ! This is stolen from send_mondo. The changes 1377c478bd9Sstevel@tonic-gate ! are those ifdef'd with IDN_MONDO 1387c478bd9Sstevel@tonic-gate ! 1397c478bd9Sstevel@tonic-gate ! construct the interrupt dispatch command register in %g1 1407c478bd9Sstevel@tonic-gate ! also, get the dispatch out as SOON as possible 1417c478bd9Sstevel@tonic-gate ! (initial analysis puts the minimum dispatch time at around 1427c478bd9Sstevel@tonic-gate ! 30-60 cycles. hence, we try to get the dispatch out quickly 1437c478bd9Sstevel@tonic-gate ! and then start the rapid check loop). 1447c478bd9Sstevel@tonic-gate ! 1457c478bd9Sstevel@tonic-gate rd %tick, %o4 ! baseline tick 1467c478bd9Sstevel@tonic-gate sll %o0, IDCR_PID_SHIFT, %g1 ! IDCR<18:14> = upa port id 1477c478bd9Sstevel@tonic-gate or %g1, IDCR_OFFSET, %g1 ! IDCR<13:0> = 0x70 1487c478bd9Sstevel@tonic-gate stxa %g0, [%g1]ASI_INTR_DISPATCH ! interrupt vector dispatch 1497c478bd9Sstevel@tonic-gate#if defined(SF_ERRATA_54) 1507c478bd9Sstevel@tonic-gate membar #Sync ! store must occur before load 1517c478bd9Sstevel@tonic-gate mov 0x20, %g3 ! UDBH Control Register Read 1527c478bd9Sstevel@tonic-gate ldxa [%g3]ASI_SDB_INTR_R, %g0 1537c478bd9Sstevel@tonic-gate#endif 1547c478bd9Sstevel@tonic-gate membar #Sync 1557c478bd9Sstevel@tonic-gate clr %o2 ! clear NACK counter 1567c478bd9Sstevel@tonic-gate clr %o3 ! clear BUSY counter 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate ! 1597c478bd9Sstevel@tonic-gate ! how long, in ticks, are we willing to wait completely 1607c478bd9Sstevel@tonic-gate ! 1617c478bd9Sstevel@tonic-gate sethi %hi(xc_tick_limit), %g2 1627c478bd9Sstevel@tonic-gate ldx [%g2 + %lo(xc_tick_limit)], %g2 1637c478bd9Sstevel@tonic-gate add %g2, %o4, %o5 ! compute the limit value 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate ! 1667c478bd9Sstevel@tonic-gate ! check the dispatch status 1677c478bd9Sstevel@tonic-gate ! 1687c478bd9Sstevel@tonic-gate.check_dispatch: 1697c478bd9Sstevel@tonic-gate ldxa [%g0]ASI_INTR_DISPATCH_STATUS, %o1 1707c478bd9Sstevel@tonic-gate brz,pn %o1, .dispatch_complete 1717c478bd9Sstevel@tonic-gate rd %tick, %g5 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate ! 1747c478bd9Sstevel@tonic-gate ! see if we've gone beyond the limit 1757c478bd9Sstevel@tonic-gate ! (can tick ever overflow?) 1767c478bd9Sstevel@tonic-gate ! 1777c478bd9Sstevel@tonic-gate.timeout_primed: 1787c478bd9Sstevel@tonic-gate sub %o5, %g5, %g2 ! limit - tick < 0 if timeout 1797c478bd9Sstevel@tonic-gate brgez,pt %g2, .check_busy 1807c478bd9Sstevel@tonic-gate inc %o3 ! bump the BUSY counter 1817c478bd9Sstevel@tonic-gate 1827c478bd9Sstevel@tonic-gate#ifdef IDN_MONDO 1837c478bd9Sstevel@tonic-gate ! 1847c478bd9Sstevel@tonic-gate ! Within the context of IDN we don't want 1857c478bd9Sstevel@tonic-gate ! to panic just because we can't send_mondo. 1867c478bd9Sstevel@tonic-gate ! Clear the dispatch register and increment 1877c478bd9Sstevel@tonic-gate ! our count of failures. 1887c478bd9Sstevel@tonic-gate ! 1897c478bd9Sstevel@tonic-gate stxa %g0, [%g1]ASI_INTR_DISPATCH 1907c478bd9Sstevel@tonic-gate sethi %hi(_idn_send_mondo_failure), %o0 1917c478bd9Sstevel@tonic-gate ld [%o0 + %lo(_idn_send_mondo_failure)], %o1 1927c478bd9Sstevel@tonic-gate inc %o1 1937c478bd9Sstevel@tonic-gate st %o1, [%o0 + %lo(_idn_send_mondo_failure)] 1947c478bd9Sstevel@tonic-gate retl 1957c478bd9Sstevel@tonic-gate mov -1, %o0 ! return (-1) 1967c478bd9Sstevel@tonic-gate#else /* IDN_MONDO */ 1977c478bd9Sstevel@tonic-gate ! 1987c478bd9Sstevel@tonic-gate ! time to die, see if we are already panicing 1997c478bd9Sstevel@tonic-gate ! 2007c478bd9Sstevel@tonic-gate mov %o0, %o1 ! save target 2017c478bd9Sstevel@tonic-gate sethi %hi(_send_mondo_nack), %o0 2027c478bd9Sstevel@tonic-gate or %o0, %lo(_send_mondo_nack), %o0 2037c478bd9Sstevel@tonic-gate sethi %hi(panicstr), %g2 2047c478bd9Sstevel@tonic-gate ldn [%g2 + %lo(panicstr)], %g2 2057c478bd9Sstevel@tonic-gate brnz %g2, .dispatch_complete ! skip if already in panic 2067c478bd9Sstevel@tonic-gate nop 2077c478bd9Sstevel@tonic-gate call panic 2087c478bd9Sstevel@tonic-gate nop 2097c478bd9Sstevel@tonic-gate#endif /* IDN_MONDO */ 2107c478bd9Sstevel@tonic-gate 2117c478bd9Sstevel@tonic-gate.check_busy: 2127c478bd9Sstevel@tonic-gate btst IDSR_BUSY, %o1 ! was it BUSY? 2137c478bd9Sstevel@tonic-gate bnz,pt %xcc, .check_dispatch 2147c478bd9Sstevel@tonic-gate nop 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate ! 2177c478bd9Sstevel@tonic-gate ! we weren't busy, we must have been NACK'd 2187c478bd9Sstevel@tonic-gate ! wait a while and send again 2197c478bd9Sstevel@tonic-gate ! (this might need jitter) 2207c478bd9Sstevel@tonic-gate ! 2217c478bd9Sstevel@tonic-gate sethi %hi(sys_clock_mhz), %g2 2227c478bd9Sstevel@tonic-gate lduw [%g2 + %lo(sys_clock_mhz)], %g2 2237c478bd9Sstevel@tonic-gate rd %tick, %g4 2247c478bd9Sstevel@tonic-gate add %g2, %g4, %g2 2257c478bd9Sstevel@tonic-gate.delay: 2267c478bd9Sstevel@tonic-gate cmp %g2, %g4 2277c478bd9Sstevel@tonic-gate bgu,pt %xcc, .delay 2287c478bd9Sstevel@tonic-gate rd %tick, %g4 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate stxa %g0, [%g1]ASI_INTR_DISPATCH ! interrupt vector dispatch 2317c478bd9Sstevel@tonic-gate#if defined(SF_ERRATA_54) 2327c478bd9Sstevel@tonic-gate membar #Sync ! store must occur before load 2337c478bd9Sstevel@tonic-gate ldxa [%g3]ASI_SDB_INTR_R, %g0 2347c478bd9Sstevel@tonic-gate#endif 2357c478bd9Sstevel@tonic-gate membar #Sync 2367c478bd9Sstevel@tonic-gate clr %o3 ! reset BUSY counter 2377c478bd9Sstevel@tonic-gate ba .check_dispatch 2387c478bd9Sstevel@tonic-gate inc %o2 ! bump the NACK counter 2397c478bd9Sstevel@tonic-gate 2407c478bd9Sstevel@tonic-gate.dispatch_complete: 2417c478bd9Sstevel@tonic-gate#ifndef IDN_MONDO 2427c478bd9Sstevel@tonic-gate#ifdef SEND_MONDO_STATS 2437c478bd9Sstevel@tonic-gate ! 2447c478bd9Sstevel@tonic-gate ! Increment the appropriate entry in a send_mondo timeout array 2457c478bd9Sstevel@tonic-gate ! x_entry[CPU][MSB]++; 2467c478bd9Sstevel@tonic-gate sub %g5, %o4, %g5 ! how long did we wait? 2477c478bd9Sstevel@tonic-gate clr %o1 ! o1 is now bit counter 2487c478bd9Sstevel@tonic-gate1: orcc %g5, %g0, %g0 ! any bits left? 2497c478bd9Sstevel@tonic-gate srlx %g5, 1, %g5 ! bits to the right 2507c478bd9Sstevel@tonic-gate bne,a,pt %xcc, 1b 2517c478bd9Sstevel@tonic-gate add %o1, 4, %o1 ! pointer increment 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate ! 2547c478bd9Sstevel@tonic-gate ! now compute the base of the x_early entry for our cpu 2557c478bd9Sstevel@tonic-gate ! 2567c478bd9Sstevel@tonic-gate CPU_INDEX(%o0, %g5) 2577c478bd9Sstevel@tonic-gate sll %o0, 8, %o0 ! 64 * 4 2587c478bd9Sstevel@tonic-gate add %o0, %o1, %o1 ! %o0 = &[CPU][delay] 2597c478bd9Sstevel@tonic-gate 2607c478bd9Sstevel@tonic-gate ! 2617c478bd9Sstevel@tonic-gate ! and increment the appropriate value 2627c478bd9Sstevel@tonic-gate ! 2637c478bd9Sstevel@tonic-gate sethi %hi(x_early), %o0 2647c478bd9Sstevel@tonic-gate or %o0, %lo(x_early), %o0 2657c478bd9Sstevel@tonic-gate ld [%o0 + %o1], %g5 2667c478bd9Sstevel@tonic-gate inc %g5 2677c478bd9Sstevel@tonic-gate st %g5, [%o0 + %o1] 2687c478bd9Sstevel@tonic-gate#endif /* SEND_MONDO_STATS */ 2697c478bd9Sstevel@tonic-gate#endif /* !IDN_MONDO */ 2707c478bd9Sstevel@tonic-gate retl 2717c478bd9Sstevel@tonic-gate#ifdef IDN_MONDO 2727c478bd9Sstevel@tonic-gate mov %g0, %o0 ! return (0) 2737c478bd9Sstevel@tonic-gate#else /* IDN_MONDO */ 2747c478bd9Sstevel@tonic-gate nop 2757c478bd9Sstevel@tonic-gate#endif /* IDN_MONDO */ 2767c478bd9Sstevel@tonic-gate SET_SIZE(idnxf_send_mondo) 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate#endif /* lint */ 2797c478bd9Sstevel@tonic-gate/* 2807c478bd9Sstevel@tonic-gate *-------------------------------------------------------- 2817c478bd9Sstevel@tonic-gate */ 2827c478bd9Sstevel@tonic-gate#if defined(lint) 2837c478bd9Sstevel@tonic-gate 2847c478bd9Sstevel@tonic-gate/*ARGSUSED*/ 2857c478bd9Sstevel@tonic-gatevoid 2867c478bd9Sstevel@tonic-gateidn_dmv_handler(void *arg) 2877c478bd9Sstevel@tonic-gate{} 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate#else /* lint */ 2907c478bd9Sstevel@tonic-gate 2917c478bd9Sstevel@tonic-gate ENTRY_NP(idn_dmv_handler) 2927c478bd9Sstevel@tonic-gate ! 2937c478bd9Sstevel@tonic-gate ! On entry: 2947c478bd9Sstevel@tonic-gate ! g1 = idn_dmv_data 2957c478bd9Sstevel@tonic-gate ! g2 = word 0 2967c478bd9Sstevel@tonic-gate ! 2977c478bd9Sstevel@tonic-gate ldx [%g1 + IDN_DMV_QBASE], %g4 ! g4 = idn_dmv_qbase 2987c478bd9Sstevel@tonic-gate add %g1, IDN_DMV_CPU, %g3 ! g3 = &idn_dmv_cpu[0] 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate CPU_INDEX(%g6, %g5) ! g6 = cpuid 3017c478bd9Sstevel@tonic-gate 3027c478bd9Sstevel@tonic-gate ! 3037c478bd9Sstevel@tonic-gate ! g5 = cur = idn_dmv_cpu[cpuid] 3047c478bd9Sstevel@tonic-gate ! 3057c478bd9Sstevel@tonic-gate sll %g6, IDN_DMV_CPU_SHIFT, %g6 ! g6 = cpuid * 8 3067c478bd9Sstevel@tonic-gate add %g3, IDN_DMV_CURRENT, %g3 3077c478bd9Sstevel@tonic-gate ld [%g6 + %g3], %g5 3087c478bd9Sstevel@tonic-gate ! 3097c478bd9Sstevel@tonic-gate ! g5 = idn_dmv_cpu[cpuid].idn_dmv_current 3107c478bd9Sstevel@tonic-gate ! offset from idn_dmv_qbase 3117c478bd9Sstevel@tonic-gate ! 3127c478bd9Sstevel@tonic-gate or %g5, %g0, %g5 ! get to 64-bits 3137c478bd9Sstevel@tonic-gate add %g5, %g4, %g5 ! g5 = idn_dmv_current 3147c478bd9Sstevel@tonic-gate ! actual address 3157c478bd9Sstevel@tonic-gate ldstub [%g5 + IV_INUSE], %g7 ! cur->iv_inuse = 0xff 3167c478bd9Sstevel@tonic-gate brz,pt %g7, 1f ! did we get it? 3177c478bd9Sstevel@tonic-gate sub %g3, IDN_DMV_CURRENT, %g4 3187c478bd9Sstevel@tonic-gate 3197c478bd9Sstevel@tonic-gate ! 3207c478bd9Sstevel@tonic-gate ! Queue is FULL. Drop interrupt. 3217c478bd9Sstevel@tonic-gate ! 3227c478bd9Sstevel@tonic-gate add %g4, IDN_DMV_LOSTINTR, %g3 3237c478bd9Sstevel@tonic-gate ld [%g6 + %g3], %g2 3247c478bd9Sstevel@tonic-gate ! 3257c478bd9Sstevel@tonic-gate ! g2 = idn_dmv_cpu[cpuid].idn_iv_lostintr++ 3267c478bd9Sstevel@tonic-gate ! 3277c478bd9Sstevel@tonic-gate inc %g2 3287c478bd9Sstevel@tonic-gate set dmv_finish_intr, %g4 3297c478bd9Sstevel@tonic-gate st %g2, [%g3 + %g6] 3307c478bd9Sstevel@tonic-gate jmp %g4 3317c478bd9Sstevel@tonic-gate mov -1, %g1 3327c478bd9Sstevel@tonic-gate ! 3337c478bd9Sstevel@tonic-gate ! not reached 3347c478bd9Sstevel@tonic-gate ! 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate1: 3377c478bd9Sstevel@tonic-gate add %g4, IDN_DMV_ACTIVE, %g7 3387c478bd9Sstevel@tonic-gate ! 3397c478bd9Sstevel@tonic-gate ! Move current pointer to next one. 3407c478bd9Sstevel@tonic-gate ! idn_dmv_current[cpuid] = cur->iv_next 3417c478bd9Sstevel@tonic-gate ! 3427c478bd9Sstevel@tonic-gate ld [%g5 + IV_NEXT], %g4 3437c478bd9Sstevel@tonic-gate st %g4, [%g3 + %g6] 3447c478bd9Sstevel@tonic-gate 3457c478bd9Sstevel@tonic-gate ! 3467c478bd9Sstevel@tonic-gate ! Start filling in structure with data. 3477c478bd9Sstevel@tonic-gate ! 3487c478bd9Sstevel@tonic-gate stx %g2, [%g5 + IV_HEAD] 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate mov IRDR_1, %g2 3517c478bd9Sstevel@tonic-gate mov IRDR_2, %g4 3527c478bd9Sstevel@tonic-gate ldxa [%g2]ASI_INTR_RECEIVE, %g2 ! g2 = xargs[0,1] 3537c478bd9Sstevel@tonic-gate ldxa [%g4]ASI_INTR_RECEIVE, %g4 ! g4 = xargs[2,3] 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate stx %g2, [%g5 + IV_XARGS0] 3567c478bd9Sstevel@tonic-gate stx %g4, [%g5 + IV_XARGS2] 3577c478bd9Sstevel@tonic-gate 3587c478bd9Sstevel@tonic-gate membar #StoreLoad|#StoreStore 3597c478bd9Sstevel@tonic-gate 3607c478bd9Sstevel@tonic-gate clrb [%g5 + IV_READY] ! cur->iv_ready = 0 (unlocked) 3617c478bd9Sstevel@tonic-gate 3627c478bd9Sstevel@tonic-gate ! 3637c478bd9Sstevel@tonic-gate ! See if we're already active, i.e. have things 3647c478bd9Sstevel@tonic-gate ! queued. If so, don't bother generating a soft 3657c478bd9Sstevel@tonic-gate ! interrupt. IDN interrupts could exhaust the 366*b0fc0e77Sgovinda ! intr_vec structs for the given cpu and that code 367*b0fc0e77Sgovinda ! doesn't know how to survive with intr_vec structs! 3687c478bd9Sstevel@tonic-gate ! 3697c478bd9Sstevel@tonic-gate ldstub [%g6 + %g7], %g7 ! idn_dmv_active = 0xff 3707c478bd9Sstevel@tonic-gate brz,a,pt %g7, 2f 371*b0fc0e77Sgovinda ldx [%g1 + IDN_SOFT_INUM], %g7 ! g7 = idn_soft_inum 3727c478bd9Sstevel@tonic-gate mov -1, %g7 3737c478bd9Sstevel@tonic-gate2: 3747c478bd9Sstevel@tonic-gate 3757c478bd9Sstevel@tonic-gate ! 3767c478bd9Sstevel@tonic-gate ! Setup to cause an IDN soft interrupt to occur, 3777c478bd9Sstevel@tonic-gate ! (if necessary). 3787c478bd9Sstevel@tonic-gate ! 3797c478bd9Sstevel@tonic-gate set dmv_finish_intr, %g3 3807c478bd9Sstevel@tonic-gate jmp %g3 3817c478bd9Sstevel@tonic-gate mov %g7, %g1 3827c478bd9Sstevel@tonic-gate 3837c478bd9Sstevel@tonic-gate SET_SIZE(idn_dmv_handler) 3847c478bd9Sstevel@tonic-gate 3857c478bd9Sstevel@tonic-gate#endif /* lint */ 386