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 + -
显示快捷键?