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