intctrl.c

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 476 行 · 第 1/2 页

C
476
字号

    ucActiveInterrupts = READ_PORT_UCHAR(PICBase);

    if (bEnabled)
    {
        ucActiveInterrupts &= ~PICMask;
    }
    else
    {
        ucActiveInterrupts |= PICMask;
    }

    WRITE_PORT_UCHAR(PICBase, ucActiveInterrupts);

    INTERRUPTS_ON();

}



// Initialize ISA interrupt controller
VOID InitPICs()
{
    //
    // First do PIC 1
    //

    // Init command 1, cascade & 4th init byte

    WRITE_PORT_UCHAR(IoPortBase+IOBASE_PIC1, 0x11);

    // Init command 2, vector interrupts to 64

    WRITE_PORT_UCHAR(IoPortBase+IOBASE_PIC1+1, 0x40);

    // Init command 3, slave on IRQ 2

    WRITE_PORT_UCHAR(IoPortBase+IOBASE_PIC1+1, 0x04);

    // Init command 4, normal EOI

    WRITE_PORT_UCHAR(IoPortBase+IOBASE_PIC1+1, 0x01);

    // Select In Service Register for reads

    WRITE_PORT_UCHAR(IoPortBase+IOBASE_PIC1, 0x0B);

    // Start with all interrupts disabled

    WRITE_PORT_UCHAR(IoPortBase+IOBASE_PIC1+1, 0xFF);

    //
    // Now do PIC 2
    //
    // Init command 1, cascade & 4th init byte

    WRITE_PORT_UCHAR(IoPortBase+IOBASE_PIC2, 0x11);

    // Init command 2, vector interrupts to 40

    WRITE_PORT_UCHAR(IoPortBase+IOBASE_PIC2+1, 0x48);

    // Init command 3, slave on IRQ 2

    WRITE_PORT_UCHAR(IoPortBase+IOBASE_PIC2+1, 0x02);

    // Init command 4, normal EOI

    WRITE_PORT_UCHAR(IoPortBase+IOBASE_PIC2+1, 0x01);

    // Select In Service Register for reads

    WRITE_PORT_UCHAR(IoPortBase+IOBASE_PIC2, 0x0B);

    // Start with all interrupts disabled

    WRITE_PORT_UCHAR(IoPortBase+IOBASE_PIC2+1, 0xFF);

    //
    // Enable interrupts from cascaded PIC
    //
    PICEnableInterrupt(ALNINTR_IRQ2, TRUE);

}

void InitPCISlotInts(void)
{
    PCI_SLOT_NUMBER     slotNumber;
    PCI_COMMON_CONFIG   pciConfig;
    int                 bus, device, function;
    int                 length;
    int                 idSel = 0;
    static BOOL         bFoundDisplay = FALSE;


    // The Boston PCI slots are located on PCI bus 0 and we know the device
    // numbers.  Scan these two slots for functions that require interrupts.
    // Add a mapping to the interrupt to/from system interrupt tables and 
    // store an interrupt ID in the PCI config space header so a device driver
    // knows what to use.
    
    bus   = 0;
    idSel = 0;

    while(1)
    {
        // Check PCI slot 2 then 3.
        if (idSel == 0)
            idSel = IDSEL_SLOT2;
        else if (idSel == IDSEL_SLOT2)
            idSel = IDSEL_SLOT3;
        else
            break;

        device = idSel - 11;
        slotNumber.u.bits.DeviceNumber = device;
    
        for (function = 0; function < PCI_MAX_FUNCTION; function++)
        {
            slotNumber.u.bits.FunctionNumber = function;
    
            length = OEMGetBusDataByOffset(PCIConfiguration, 
                                           bus, 
                                           slotNumber.u.AsULONG,
                                           &pciConfig, 
                                           0,
                                           sizeof(pciConfig) - sizeof(pciConfig.DeviceSpecific));
		
            // No more functions to find in this device range...
            if (length == 0 || pciConfig.VendorID == 0xFFFF)
            {
                break;
            }

            // NOTE: at the moment - we only support video plug-in cards.
            if (pciConfig.BaseClass == PCI_CLASS_DISPLAY_CTLR &&
                pciConfig.u.type0.InterruptLine <= ALNINTR_PCI_INTD &&
                pciConfig.u.type0.InterruptLine >= ALNINTR_PCI_INTA)
            {

                if (bFoundDisplay)
                {
                    EdbgOutputDebugString("WARNING: Only one display controller supported in this system.\r\n");
                    return;
                }
              
                bFoundDisplay = TRUE;

                // Set up interrupt to/from sysintr value mappings...
                IMAP_Aln2Sys[pciConfig.u.type0.InterruptLine] = SYSINTR_VIDEO;
                IMAP_Sys2Aln[SYSINTR_VIDEO] = pciConfig.u.type0.InterruptLine;

                // Set bits to enable interrupt at host-pci bridge...
                switch(pciConfig.u.type0.InterruptLine)
                {
                case ALNINTR_PCI_INTA:
                    DefIControlHigh |= 0x00000008;
                    break;
                case ALNINTR_PCI_INTB:
                case ALNINTR_PCI_INTC:
                    EdbgOutputDebugString("WARNING: Video card in slot %c is configured with a bad interrupt line setting.\r\n", (idSel == IDSEL_SLOT2 ? '3' : '4'));
                    // Since we know what the interrupt line value should be
                    // (based on the slot the card's in and assuming it's a
                    // single-function card), we'll configure the enable.  The
                    // above is a warning because the driver may read the 
                    // interrupt line value from the configuration register,
                    // map it to a sysintr value and call InterruptInitialize()
                    // with a bad sysintr value.
                    if (idSel == IDSEL_SLOT2)
                        DefIControlHigh |= 0x00008000;    // Use INTD.
                    else if (idSel == IDSEL_SLOT3)
                        DefIControlHigh |= 0x00000008;    // Use INTA.
                    break;
                case ALNINTR_PCI_INTD:
                    DefIControlHigh |= 0x00008000;
                    break;
                default:
                    break;
                }

            }
            else if(pciConfig.u.type0.InterruptLine <= ALNINTR_PCI_INTD &&
                    pciConfig.u.type0.InterruptLine >= ALNINTR_PCI_INTA)
            {
                // There's a card here that is configured for interrupts, but
                // it's not a video card.  Since we're not going to walk through
                // the class and subclass types to assign a meaningful sysintr
                // value, we'll assign a sysintr value based on the slot it's
                // in.  The driver for this device could store the sysintr
                // value in the registry if the card's location was never to
                // change (bad idea) or it would get the interrupt line value
                // from the device's PCI configuration space, call the OAL's
                // IOCTL_HAL_MAP_INTERRUPT (IOCTL_HAL_TRANSLATE_IRQ) to map it
                // to a sysintr value, then use this value in a call to 
                // InterruptInitialize, thus allowing the card to roam the
                // slots without problem.

// *** NOTE: The following code should be commented out when using a plug-in
// ***       NIC for EDBG (e.g., when not using the built-in DEC21140)
//#if 0
                if (idSel == IDSEL_SLOT2 && pciConfig.u.type0.InterruptLine == ALNINTR_PCI_INTD)
                {
                    DefIControlHigh |= 0x00008000;    // Use INTD.

                    // NOTE: IDSEL_SLOT2 is really physical slot #3.
                    IMAP_Aln2Sys[ALNINTR_PCI_INTD]  = SYSINTR_GEN_SLOT3;
                    IMAP_Sys2Aln[SYSINTR_GEN_SLOT3] = ALNINTR_PCI_INTD;
                }
                else if (idSel == IDSEL_SLOT3 && pciConfig.u.type0.InterruptLine == ALNINTR_PCI_INTA)
                {
                    DefIControlHigh |= 0x00000008;    // Use INTA.

                    // NOTE: IDSEL_SLOT3 is really physical slot #4.
                    IMAP_Aln2Sys[ALNINTR_PCI_INTA]  = SYSINTR_GEN_SLOT4;
                    IMAP_Sys2Aln[SYSINTR_GEN_SLOT4] = ALNINTR_PCI_INTA;
                }
                else
                    EdbgOutputDebugString("WARNING: Card in slot %c is configured with a bad interrupt line setting.  No sysintr mapping established.\r\n", (idSel == IDSEL_SLOT2 ? '3' : '4'));

//#endif	// 0.

            }

            // If we didn't see it and it's not a multifunction device...
            if (function == 0 && !(pciConfig.HeaderType & 0x80))
            {					
                break;
            }
			
        }

    }

    return;
    
}

⌨️ 快捷键说明

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