via.c

来自「linux 内核源代码」· C语言 代码 · 共 655 行 · 第 1/2 页

C
655
字号
		printk(KERN_DEBUG "VIA2:  IFR = 0x%02X  IER = 0x%02X\n",			(uint) via2[rIFR], (uint) via2[rIER]);		printk(KERN_DEBUG "      SIFR = 0x%02X SIER = 0x%02X\n",			(uint) via2[rSIFR], (uint) via2[rSIER]);	} else {		printk(KERN_DEBUG "VIA2: DDRA = 0x%02X DDRB = 0x%02X ACR = 0x%02X\n",			(uint) via2[vDirA], (uint) via2[vDirB],			(uint) via2[vACR]);		printk(KERN_DEBUG "         PCR = 0x%02X  IFR = 0x%02X IER = 0x%02X\n",			(uint) via2[vPCR],			(uint) via2[vIFR], (uint) via2[vIER]);	}}/* * This is always executed with interrupts disabled. * * TBI: get time offset between scheduling timer ticks */unsigned long mac_gettimeoffset (void){	unsigned long ticks, offset = 0;	/* read VIA1 timer 2 current value */	ticks = via1[vT1CL] | (via1[vT1CH] << 8);	/* The probability of underflow is less than 2% */	if (ticks > MAC_CLOCK_TICK - MAC_CLOCK_TICK / 50)		/* Check for pending timer interrupt in VIA1 IFR */		if (via1[vIFR] & 0x40) offset = TICK_SIZE;	ticks = MAC_CLOCK_TICK - ticks;	ticks = ticks * 10000L / MAC_CLOCK_TICK;	return ticks + offset;}/* * Flush the L2 cache on Macs that have it by flipping * the system into 24-bit mode for an instant. */void via_flush_cache(void){	via2[gBufB] &= ~VIA2B_vMode32;	via2[gBufB] |= VIA2B_vMode32;}/* * Return the status of the L2 cache on a IIci */int via_get_cache_disable(void){	/* Safeguard against being called accidentally */	if (!via2) {		printk(KERN_ERR "via_get_cache_disable called on a non-VIA machine!\n");		return 1;	}	return (int) via2[gBufB] & VIA2B_vCDis;}/* * Initialize VIA2 for Nubus access */void __init via_nubus_init(void){	/* unlock nubus transactions */	if ((macintosh_config->adb_type != MAC_ADB_PB1) &&	    (macintosh_config->adb_type != MAC_ADB_PB2)) {		/* set the line to be an output on non-RBV machines */		if (!rbv_present)			via2[vDirB] |= 0x02;		/* this seems to be an ADB bit on PMU machines */		/* according to MkLinux.  -- jmt               */		via2[gBufB] |= 0x02;	}	/* Disable all the slot interrupts (where possible). */	switch (macintosh_config->via_type) {	case MAC_VIA_II:		/* Just make the port A lines inputs. */		switch(macintosh_config->ident) {		case MAC_MODEL_II:		case MAC_MODEL_IIX:		case MAC_MODEL_IICX:		case MAC_MODEL_SE30:			/* The top two bits are RAM size outputs. */			via2[vDirA] &= 0xC0;			break;		default:			via2[vDirA] &= 0x80;		}		break;	case MAC_VIA_IIci:		/* RBV. Disable all the slot interrupts. SIER works like IER. */		via2[rSIER] = 0x7F;		break;	case MAC_VIA_QUADRA:		/* Disable the inactive slot interrupts by making those lines outputs. */		if ((macintosh_config->adb_type != MAC_ADB_PB1) &&		    (macintosh_config->adb_type != MAC_ADB_PB2)) {			via2[vBufA] |= 0x7F;			via2[vDirA] |= 0x7F;		}		break;	}}/* * The generic VIA interrupt routines (shamelessly stolen from Alan Cox's * via6522.c :-), disable/pending masks added. */irqreturn_t via1_irq(int irq, void *dev_id){	int irq_num;	unsigned char irq_bit, events;	events = via1[vIFR] & via1[vIER] & 0x7F;	if (!events)		return IRQ_NONE;	irq_num = VIA1_SOURCE_BASE;	irq_bit = 1;	do {		if (events & irq_bit) {			via1[vIFR] = irq_bit;			m68k_handle_int(irq_num);		}		++irq_num;		irq_bit <<= 1;	} while (events >= irq_bit);#if 0 /* freakin' pmu is doing weird stuff */	if (!oss_present) {		/* This (still) seems to be necessary to get IDE		   working.  However, if you enable VBL interrupts,		   you're screwed... */		/* FIXME: should we check the SLOTIRQ bit before                   pulling this stunt? */		/* No, it won't be set. that's why we're doing this. */		via_irq_disable(IRQ_MAC_NUBUS);		via_irq_clear(IRQ_MAC_NUBUS);		m68k_handle_int(IRQ_MAC_NUBUS);		via_irq_enable(IRQ_MAC_NUBUS);	}#endif	return IRQ_HANDLED;}irqreturn_t via2_irq(int irq, void *dev_id){	int irq_num;	unsigned char irq_bit, events;	events = via2[gIFR] & via2[gIER] & 0x7F;	if (!events)		return IRQ_NONE;	irq_num = VIA2_SOURCE_BASE;	irq_bit = 1;	do {		if (events & irq_bit) {			via2[gIFR] = irq_bit | rbv_clear;			m68k_handle_int(irq_num);		}		++irq_num;		irq_bit <<= 1;	} while (events >= irq_bit);	return IRQ_HANDLED;}/* * Dispatch Nubus interrupts. We are called as a secondary dispatch by the * VIA2 dispatcher as a fast interrupt handler. */irqreturn_t via_nubus_irq(int irq, void *dev_id){	int slot_irq;	unsigned char slot_bit, events;	events = ~via2[gBufA] & 0x7F;	if (rbv_present)		events &= via2[rSIER];	else		events &= ~via2[vDirA];	if (!events)		return IRQ_NONE;	do {		slot_irq = IRQ_NUBUS_F;		slot_bit = 0x40;		do {			if (events & slot_bit) {				events &= ~slot_bit;				m68k_handle_int(slot_irq);			}			--slot_irq;			slot_bit >>= 1;		} while (events); 		/* clear the CA1 interrupt and make certain there's no more. */		via2[gIFR] = 0x02 | rbv_clear;		events = ~via2[gBufA] & 0x7F;		if (rbv_present)			events &= via2[rSIER];		else			events &= ~via2[vDirA];	} while (events);	return IRQ_HANDLED;}void via_irq_enable(int irq) {	int irq_src	= IRQ_SRC(irq);	int irq_idx	= IRQ_IDX(irq);#ifdef DEBUG_IRQUSE	printk(KERN_DEBUG "via_irq_enable(%d)\n", irq);#endif	if (irq_src == 1) {		via1[vIER] = IER_SET_BIT(irq_idx);	} else if (irq_src == 2) {		if (irq != IRQ_MAC_NUBUS || nubus_disabled == 0)			via2[gIER] = IER_SET_BIT(irq_idx);	} else if (irq_src == 7) {		switch (macintosh_config->via_type) {		case MAC_VIA_II:			nubus_disabled &= ~(1 << irq_idx);			/* Enable the CA1 interrupt when no slot is disabled. */			if (!nubus_disabled)				via2[gIER] = IER_SET_BIT(1);			break;		case MAC_VIA_IIci:			/* On RBV, enable the slot interrupt.			 * SIER works like IER.			 */			via2[rSIER] = IER_SET_BIT(irq_idx);			break;		case MAC_VIA_QUADRA:			/* Make the port A line an input to enable the slot irq.			 * But not on PowerBooks, that's ADB.			 */			if ((macintosh_config->adb_type != MAC_ADB_PB1) &&			    (macintosh_config->adb_type != MAC_ADB_PB2))				via2[vDirA] &= ~(1 << irq_idx);			break;		}	}}void via_irq_disable(int irq) {	int irq_src	= IRQ_SRC(irq);	int irq_idx	= IRQ_IDX(irq);#ifdef DEBUG_IRQUSE	printk(KERN_DEBUG "via_irq_disable(%d)\n", irq);#endif	if (irq_src == 1) {		via1[vIER] = IER_CLR_BIT(irq_idx);	} else if (irq_src == 2) {		via2[gIER] = IER_CLR_BIT(irq_idx);	} else if (irq_src == 7) {		switch (macintosh_config->via_type) {		case MAC_VIA_II:			nubus_disabled |= 1 << irq_idx;			if (nubus_disabled)				via2[gIER] = IER_CLR_BIT(1);			break;		case MAC_VIA_IIci:			via2[rSIER] = IER_CLR_BIT(irq_idx);			break;		case MAC_VIA_QUADRA:			if ((macintosh_config->adb_type != MAC_ADB_PB1) &&			    (macintosh_config->adb_type != MAC_ADB_PB2))				via2[vDirA] |= 1 << irq_idx;			break;		}	}}void via_irq_clear(int irq) {	int irq_src	= IRQ_SRC(irq);	int irq_idx	= IRQ_IDX(irq);	int irq_bit	= 1 << irq_idx;	if (irq_src == 1) {		via1[vIFR] = irq_bit;	} else if (irq_src == 2) {		via2[gIFR] = irq_bit | rbv_clear;	} else if (irq_src == 7) {		/* FIXME: There is no way to clear an individual nubus slot		 * IRQ flag, other than getting the device to do it.		 */	}}/* * Returns nonzero if an interrupt is pending on the given * VIA/IRQ combination. */int via_irq_pending(int irq){	int irq_src	= IRQ_SRC(irq);	int irq_idx	= IRQ_IDX(irq);	int irq_bit	= 1 << irq_idx;	if (irq_src == 1) {		return via1[vIFR] & irq_bit;	} else if (irq_src == 2) {		return via2[gIFR] & irq_bit;	} else if (irq_src == 7) {		/* Always 0 for MAC_VIA_QUADRA if the slot irq is disabled. */		return ~via2[gBufA] & irq_bit;	}	return 0;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?