setipl(eframe->tf_mask);
m188_setipl(eframe->tf_mask);
m188_ext_int(u_int v, struct trapframe *eframe){	int cpu = cpu_number();	unsigned int cur_mask;	unsigned int level, old_spl;	struct intrhand *intr;	intrhand_t *list;	int ret, intbit;	unsigned vec;	cur_mask = ISR_GET_CURRENT_MASK(cpu);	old_spl = m188_curspl[cpu];	eframe->tf_mask = old_spl;	if (cur_mask == 0) {		/*		 * Spurious interrupts - may be caused by debug output clearing		 * DUART interrupts.		 */		flush_pipeline();		goto out;	}	uvmexp.intrs++;	/*	 * We want to service all interrupts marked in the IST register	 * They are all valid because the mask would have prevented them	 * from being generated otherwise.  We will service them in order of	 * priority.	 */	do {		level = safe_level(cur_mask, old_spl);		if (old_spl >= level) {			int i;			printf("safe level %d <= old level %d\n", level, old_spl);			printf("cur_mask = 0x%b\n", cur_mask, IST_STRING);			for (i = 0; i < 4; i++)				printf("IEN%d = 0x%b  ", i, *int_mask_reg[i], IST_STRING);			printf("\nCPU0 spl %d  CPU1 spl %d  CPU2 spl %d  CPU3 spl %d\n",			       m188_curspl[0], m188_curspl[1],			       m188_curspl[2], m188_curspl[3]);			for (i = 0; i < 8; i++)				printf("int_mask[%d] = 0x%08x\n", i, int_mask_val[i]);			printf("--CPU %d halted--\n", cpu_number());			spl7();			for(;;) ;		}#ifdef DEBUG		if (level > 7 || (int)level < 0) {			panic("int level (%x) is not between 0 and 7", level);		}#endif		setipl(level);		/*		 * Do not enable interrupts yet if we know, from cur_mask,		 * that we have not cleared enough conditions yet.		 * For now, only the timer interrupt requires its condition		 * to be cleared before interrupts are enabled.		 */		if ((cur_mask & DTI_BIT) == 0) {			enable_interrupt();		}		/* generate IACK and get the vector */		/*		 * This is tricky.  If you don't catch all the		 * interrupts, you die. Game over. Insert coin...		 * XXX smurph		 */		/* find the first bit set in the current mask */		intbit = ff1(cur_mask);		if (OBIO_INTERRUPT_MASK & (1 << intbit)) {			vec = SYSCON_VECT + obio_vec[intbit];			if (vec == 0) {				panic("unknown onboard interrupt: mask = 0x%b",				    1 << intbit, IST_STRING);			}		} else if (HW_FAILURE_MASK & (1 << intbit)) {			vec = SYSCON_VECT + obio_vec[intbit];			if (vec == 0) {				panic("unknown hardware failure: mask = 0x%b",				    1 << intbit, IST_STRING);			}		} else if (VME_INTERRUPT_MASK & (1 << intbit)) {			if (guarded_access(ivec[level], 4, (u_char *)&vec) ==			    EFAULT) {				panic("unable to get vector for this vmebus "				    "interrupt (level %x)", level);			}			vec &= VME_VECTOR_MASK;			if (vec & VME_BERR_MASK) {				printf("VME vec timeout, vec = %x, mask = 0x%b\n",				    vec, 1 << intbit, IST_STRING);				break;			}			if (vec == 0) {				panic("unknown vme interrupt: mask = 0x%b",				    1 << intbit, IST_STRING);			}		} else {			panic("unknown interrupt: level = %d intbit = 0x%x "			    "mask = 0x%b",			    level, intbit, 1 << intbit, IST_STRING);		}		list = &intr_handlers[vec];		if (SLIST_EMPTY(list)) {			/* increment intr counter */			intrcnt[M88K_SPUR_IRQ]++;			printf("Spurious interrupt: level = %d vec = 0x%x, "			    "intbit = %d mask = 0x%b\n",			    level, vec, intbit, 1 << intbit, IST_STRING);		} else {			/*			 * Walk through all interrupt handlers in the chain			 * for the given vector, calling each handler in turn,			 * till some handler returns a value != 0.			 */			ret = 0;			SLIST_FOREACH(intr, list, ih_link) {				if (intr->ih_wantframe != 0)					ret = (*intr->ih_fn)((void *)eframe);				else					ret = (*intr->ih_fn)(intr->ih_arg);				if (ret != 0) {					intrcnt[level]++;					intr->ih_count.ec_count++;					break;				}			}			if (ret == 0) {				printf("Unclaimed interrupt: level = %d "				    "vec = 0x%x, intbit = %d mask = 0x%b\n",				    level, vec, intbit,				    1 << intbit, IST_STRING);				break;			}		}	} while ((cur_mask = ISR_GET_CURRENT_MASK(cpu)) != 0);	/*	 * process any remaining data access exceptions before	 * returning to assembler	 */	disable_interrupt();out:	if (eframe->tf_dmt0 & DMT_VALID)		m88100_trap(T_DATAFLT, eframe);	/*	 * Restore the mask level to what it was when the interrupt	 * was taken.	 */	setipl(eframe->tf_mask);}