pciconfig.c
来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 1,063 行 · 第 1/3 页
C
1,063 行
/* -*-C-*-
*
* $Revision: 1.8 $
* $Author: kwelton $
* $Date: 2000/08/08 21:45:52 $
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
* PARTICULAR PURPOSE.
*
* Copyright (c) 1995, 1996, 1997, 1998 Microsoft Corporation
* Copyright (c) 1999, 2000 ARM Limited
* All Rights Reserved
*/
#include <windows.h>
#include <ceddk.h>
#include "pcilib.h"
#include "platform.h"
#include "cdefs.h"
#include "arm_ddk.h"
/*
* Where in IO and Memory do we start allocating PCI space from?
*/
unsigned int PCI_IOBase = PCI_IO_ALLOCATION_BASE;
unsigned int PCI_MemBase = PHYS_PCI_MEM_BASE; // Virtual addr instead ?
/*
* structures for holding PCI hierarchy information
*/
#define MAX_PCIDEVICES 128
int PCIDevicesInitialised = FALSE;
PCIDevice_t StaticPCIDevices[MAX_PCIDEVICES];
PCIDevice_t *freePCIDevices = NULL;
PCIDevice_t *PCIDeviceList = NULL;
PCIDevice_t *PCIroot = NULL;
#define MAX(val1, val2) (((val1) > (val2)) ? (val1) : (val2))
static LPSTR BaseClass[] =
{
"PRE_20",
"MASS_STORAGE_CTLR",
"NETWORK_CTLR",
"DISPLAY_CTLR",
"MULTIMEDIA_DEV",
"MEMORY_CTLR",
"BRIDGE_DEV",
"SIMPLE_COMMS_CTLR",
"BASE_SYSTEM_DEV",
"INPUT_DEV",
"DOCKING_STATION",
"PROCESSOR",
"SERIAL_BUS_CTLR"
};
typedef struct _DEVICETABLE
{
WORD wDeviceID;
LPSTR szDevName;
} DEVICETABLE, *PDEVICETABLE;
typedef struct _VENDORTABLE
{
WORD wVendorID;
LPSTR szVendorName;
PDEVICETABLE pDeviceTable;
DWORD dwTableSize;
} VENDORTABLE, *PVENDORTABLE;
static DEVICETABLE devIntel[] =
{
{0x1960, "i960 ATU"},
{0x0960, "i960"},
{0x7000, "PIIX3 PCI-ISA Bridge"},
{0x122E, "PIIX PCI-ISA Bridge"},
{0x7010, "PIIX3 IDE Interface"},
{0x1230, "PIIX IDE Interface"},
{0x7100, "430TX MTXC"},
{0x1250, "430HX TXC"}
};
static DEVICETABLE devDigital[] =
{
{0x0019, "21143 ether"},
{0x0009, "21140 ether"},
{0x0022, "21150 pci-pci"}
};
static DEVICETABLE devNational[] =
{
{0x0002, "87560 IDE"},
{0x000E, "87560 I/O"},
{0x0011, "87560 I/O"},
{0x0012, "87560 USB"}
};
static DEVICETABLE devS3[] =
{
{0x5631, "ViRGE"},
{0x8C05, "ViRGE"}
};
static DEVICETABLE devEctiva[] =
{
{0xC935, "EV1936 MachOne Plus"}
};
static DEVICETABLE devCirrus[] =
{
{0x00B8, "CL-GD5446"}
};
static DEVICETABLE devTI[] =
{
{0xAC16, "PCI1250A"}
};
static VENDORTABLE vendors[] =
{
{0x8086, "Intel", devIntel,
sizeof(devIntel) / sizeof(DEVICETABLE)},
{0x1011, "Digital", devDigital,
sizeof(devDigital) / sizeof(DEVICETABLE)},
{0x100B, "National", devNational,
sizeof(devNational) / sizeof(DEVICETABLE)},
{0x5333, "S3", devS3,
sizeof(devS3) / sizeof(DEVICETABLE)},
{0x1045, "Ectiva", devEctiva,
sizeof(devEctiva) / sizeof(DEVICETABLE)},
{0x1013, "Cirrus Logic", devCirrus,
sizeof(devCirrus) / sizeof(DEVICETABLE)},
{0x104C, "TI", devTI,
sizeof(devTI) / sizeof(DEVICETABLE)},
{0,0,0,0}
};
#define NUMVENDORS (sizeof(vendors)/sizeof(VENDORTABLE))
static BOOL PrintVendorString(WORD wVendor, WORD wDevice)
{
DWORD v,d;
for (v = 0; v < NUMVENDORS; v++)
{
if (wVendor == vendors[v].wVendorID)
{
for (d = 0; d < vendors[v].dwTableSize; d++)
{
if (wDevice == (vendors[v].pDeviceTable)[d].wDeviceID)
{
DPF("%s (%s)", vendors[v].szVendorName,
(vendors[v].pDeviceTable)[d].szDevName);
return TRUE;
}
}
DPF("%a (0x%H)", vendors[v].szVendorName,
(vendors[v].pDeviceTable)[d].wDeviceID);
return TRUE;
}
}
return FALSE;
}
/**********************************************************************/
static unsigned int ALIGN(unsigned int val, unsigned int align)
{
/*
* if the value is zero, it is aligned, no matter what the size
*/
if (val == 0)
return val;
/*
* if the value is less than the alignment, return the alignment
*/
if (val < align)
return align;
/*
* finally, if there is need to move the value upwards, do so
*/
if ((val & ~(align - 1)) != 0)
return (((val) + ((align) - 1)) & ~((align) - 1));
else
return val;
}
int GetPCIConfig(ULONG bus, ULONG device, ULONG function,
PCI_COMMON_CONFIG *pConfig)
{
PCI_SLOT_NUMBER slotNumber;
int length;
slotNumber.u.AsULONG = 0;
slotNumber.u.bits.DeviceNumber = device;
slotNumber.u.bits.FunctionNumber = function;
length = PCIGetBusDataByOffset(bus, slotNumber.u.AsULONG, pConfig,
0, sizeof(PCI_COMMON_CONFIG));
return length;
}
int SetPCIConfig(ULONG bus, ULONG device, ULONG function,
PCI_COMMON_CONFIG *pConfig)
{
PCI_SLOT_NUMBER slotNumber;
int length;
slotNumber.u.AsULONG = 0;
slotNumber.u.bits.DeviceNumber = device;
slotNumber.u.bits.FunctionNumber = function;
length = PCISetBusDataByOffset(bus, slotNumber.u.AsULONG, pConfig,
0, sizeof(PCI_COMMON_CONFIG));
return length;
}
/*
* Routine: PCI_AllocateMemSpace
*
* Description: Allocate space in PCI memory
*
* Returns: Base address of allocated PCI memory space
*
* Note: Calling this code has a side effect of moving the global
* Memory base on.
*/
static DWORD PCI_AllocateMemSpace(DWORD size)
{
DWORD alignto;
DWORD base;
/*
* align in minimum sized chunks of DEFAULT_MEMORY_ALIGNMENT
*/
alignto = MAX(size, DEFAULT_MEMORY_ALIGNMENT);
base = ALIGN(PCI_MemBase, alignto);
PCI_MemBase = base + size;
return base;
}
/*
* Routine: PCI_AllocateInterrupt
*
* Description: Allocate an interrupt #
*
* Returns: Nothing
*
*/
static void PCI_AllocateInterrupt(PCIDevice_t * device)
{
unsigned char pin = 0;
unsigned char interrupt = 0xFF;
// NOTE: we only support single function PCI devices in the slots and since
// we don't use compact PCI, we won't worry about the 21152.
// read the interrupt pin from the device
pin = OEM_ReadConfigByte(device->bus, device->slot, device->func,
PCI_INTERRUPT_PIN);
// If the device doesn't use interrupts, return.
if (!pin)
return;
// Assign an interrupt to function 0 per a slot.
if (!device->func)
{
switch(device->slot)
{
case PCI_SLOT1:
interrupt = IRQ_PCIINT3; // PCI Slot 1 INTA = System INTD
break;
case PCI_SLOT2:
interrupt = IRQ_PCIINT2; // PCI Slot 2 INTA = System INTC
break;
case PCI_SLOT3:
interrupt = IRQ_PCIINT1; // PCI Slot 3 INTA = System INTB
break;
default:
interrupt = 0xFF;
}
}
else
{
EdbgOutputDebugString("WARNING: multiple function interrupts not supported.\r\n");
return;
}
EdbgOutputDebugString("INFO: Assigning IRQ=0x%x to PCI function=0x%x in slot=0x%x\r\n", interrupt, device->func, device->slot);
/*
* write it to the device (this will be read later by a
* device driver
*/
OEM_WriteConfigByte(device->bus, device->slot, device->func,
PCI_INTERRUPT_LINE, interrupt);
return;
#if 0
PCIDevice_t *curr;
unsigned char pin;
unsigned char interrupt;
// read the interrupt pin from the device
pin = OEM_ReadConfigByte(device->bus, device->slot, device->func,
PCI_INTERRUPT_PIN);
// figure out the interrupt number
if (device->bus == 0)
{
/*
* Primary bus
* pin is this device's pin
* curr is this device
*/
curr = device;
}
else
{
/*
* Secondary bus or beyond
*/
curr = device;
while (curr->bus != 0)
{
/*
* swizzle the interrupt pins through each PCI-PCI bridge
*/
pin = bridgeSwizzle (pin, curr->slot);
curr = curr->parent;
}
/*
* pin is now the pin of the last bridge
* curr is the last PCI-PCI bridge
*/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?