/// <summary> /// Adds an IRQ to the table /// </summary> /// <param name="slot">The slot</param> /// <param name="pin">The pin</param> /// <param name="irq">The IRQ</param> private static void addIRQ(uint slot, uint pin, uint irq, uint polarity, uint trigger) { if (slot >= PCI_BUS_DEV_MAX || pin > PCI_PINS) { Panic.DoPanic("[PCI] Invalid IRQ added"); } PciIRQEntry entry = new PciIRQEntry(); entry.Irq = irq; entry.Flags = 0; if (polarity == 0 || polarity == 3) { entry.Flags |= IOApic.IOAPIC_REDIR_POLARITY_LOW; } else { entry.Flags |= IOApic.IOAPIC_REDIR_POLARITY_HIGH; } if (trigger == 0 || trigger == 3) { entry.Flags |= IOApic.IOAPIC_REDIR_TRIGGER_LEVEL; } else { entry.Flags |= IOApic.IOAPIC_REDIR_TRIGGER_EDGE; } m_irqTable[(slot * PCI_PINS) + pin] = entry; }
/// <summary> /// Sets an interrupt handler for a PCI device /// </summary> /// <param name="dev">The device</param> public static void SetInterruptHandler(PciDevice dev, IRQ.IRQHandler handler) { // Get IRQ routing data from table PciIRQEntry irq = m_irqTable[(dev.Slot * PCI_PINS) + (dev.IRQPin - 1)]; uint irqNum = irq.Irq; // If no routing exists, use the interrupt line if (irqNum == 0) { irqNum = dev.IRQLine; } // First set the IRQ handler to avoid race conditions IRQ.SetHandler(irqNum, handler); IOApicManager.CreateEntry(irqNum, irqNum, irq.Flags); // Info Console.Write("[PCI] Set device to use IRQ "); Console.WriteNum((int)irqNum); Console.Write('\n'); }