📄 pciinit.c
字号:
return(FALSE);
}
*pMemSize += SecondaryMemSize;
*pIoSize += SecondaryIoSize;
return(TRUE);
}
BOOL
PciInitCheckBARs(
ULONG Bus,
ULONG Device,
ULONG Function,
ULONG NumberOfRegs,
PULONG pMemSize,
PULONG pIoSize
)
{
ULONG Offset;
ULONG i;
ULONG BaseAddress;
ULONG Size;
ULONG Type;
DEBUGMSG(ZONE_FUNCTION, (TEXT("InitCheckBars %d %d %d\r\n"), Bus, Device, Function));
Offset = 0x10;
for (i = 0; i < NumberOfRegs; i++) {
PCIConfig_Write(Bus,Device,Function,Offset,0xFFFFFFFF);
BaseAddress = PCIConfig_Read(Bus,Device,Function,Offset);
DEBUGMSG(ZONE_INFO, (TEXT("ICB: Offset (0x%B) = 0x%X\r\n"), Offset, BaseAddress));
if (BaseAddress & 1) {
//
// IO space
//
Size = ~(BaseAddress & 0xFFFFFFFC);
Type = PCI_TYPE_IO;
} else {
//
// memory space
// BUGBUG - don't properly handle the MEM20 case
//
Size = ~(BaseAddress & 0xFFFFFFF0);
Type = PCI_TYPE_MEM;
}
//
// check that the register is valid format
// should have consecutive high 1's and consecutive low 0's
//
if ((BaseAddress != 0) &&
(BaseAddress != 0xFFFFFFFF) &&
((Size + 1) & Size) == 0) {
//
// Add to list so allocate space later
//
SpaceDesc[nSpaceDesc].Bus = Bus;
SpaceDesc[nSpaceDesc].Device = Device;
SpaceDesc[nSpaceDesc].Function = Function;
SpaceDesc[nSpaceDesc].Offset = Offset;
SpaceDesc[nSpaceDesc].Bridge = 0;
SpaceDesc[nSpaceDesc].IoSize = 0;
SpaceDesc[nSpaceDesc].MemSize = 0;
if (Type == PCI_TYPE_IO) {
*pIoSize += Size + 1;
SpaceDesc[nSpaceDesc].IoSize = Size + 1;
} else {
*pMemSize += Size + 1;
SpaceDesc[nSpaceDesc].MemSize = Size + 1;
}
DEBUGMSG(ZONE_INFO, (TEXT("BAR %d %d %d 0x%X %d 0x%X %s\r\n",
Bus,Device,Function,Offset,Type,
Size+1,(Type == PCI_TYPE_IO)? "IO":"MEM")));
nSpaceDesc++;
if (nSpaceDesc == MAX_SPACE) {
RETAILMSG(1, (TEXT("ERROR: MAX_SPACE.\r\n")));
return(FALSE);
}
}
//
// check for 64 bit device - BAR is twice as big
//
if ((BaseAddress & 0x7) == 0x4) {
//
// 64 bit device - BAR is twice as wide - zero out high part
//
Offset += 4;
PCIConfig_Write(Bus,Device,Function,Offset,0x0);
}
Offset += 4;
}
return(TRUE);
}
BOOL
PciInitAllocateIoSpace(
ULONG IoUpperBound,
ULONG IoLowerBound,
ULONG Bus
)
{
ULONG i;
ULONG j;
ULONG IoBase;
PSPACE_DESC pSpace;
DEBUGMSG(ZONE_FUNCTION, (TEXT("AllocateIo %d %X %X\r\n"), Bus, IoUpperBound, IoLowerBound));
//
// Sort the space descriptors for a given bus by size
//
for (i = 31; i >= 1; i--) {
for (j = 0; j < nSpaceDesc; j++) {
pSpace = &SpaceDesc[j];
if ((pSpace->Bus == Bus) && ((pSpace->IoSize) & (1 << i))) {
if (pSpace->Bridge == 0) {
IoUpperBound -= pSpace->IoSize;
PCIConfig_Write(pSpace->Bus,
pSpace->Device,
pSpace->Function,
pSpace->Offset,
IoUpperBound);
pSpace->IoBase = IoUpperBound;
pSpace->SortOrder = SortOrder++;
DEBUGMSG(ZONE_INFO, (TEXT("AllocateIO %d %d %d %x %x (%X)\r\n"),
pSpace->Bus, pSpace->Device,
pSpace->Function, pSpace->Offset,
IoUpperBound,pSpace->IoSize));
} else {
if (!PciInitAllocateIoSpace(
IoUpperBound,
IoUpperBound - pSpace->IoSize,
pSpace->SecondaryBus)) {
return(FALSE);
}
//
// init I/O base and limit registers
//
IoBase = PCIConfig_Read(pSpace->Bus,
pSpace->Device,
pSpace->Function,
PCIBRIDGE_IO);
((PBRIDGE_IO)(&IoBase))->IoLimit.Address =
(BYTE)(((IoUpperBound - 1) & 0xF000) >> 12);
//((PBRIDGE_IO)(&IoBase))->IoLimit.DecodeType = Something;
IoUpperBound -= pSpace->IoSize;
((PBRIDGE_IO)(&IoBase))->IoBase.Address =
(BYTE)(((IoUpperBound) & 0xF000) >> 12);
//((PBRIDGE_IO)(&IoBase))->IoBase.DecodeType = Something;
DEBUGMSG(ZONE_INFO, (TEXT("AllocateIOLimit %d %d %d %x %x (%X)\r\n"),
pSpace->Bus, pSpace->Device,
pSpace->Function, pSpace->Offset,
IoBase,pSpace->IoSize));
PCIConfig_Write(pSpace->Bus,
pSpace->Device,
pSpace->Function,
PCIBRIDGE_IO,
IoBase);
//
// Now enable the I/O and memory accesses...
//
PCIConfig_Write(pSpace->Bus,
pSpace->Device,
pSpace->Function,
PCI_CONFIG_COMMAND_STATUS,
0x7);
pSpace->IoBase = IoBase;
pSpace->SortOrder = SortOrder++;
}
}
if (IoUpperBound < IoLowerBound) {
return(FALSE);
}
}
}
return(TRUE);
}
BOOL
PciInitAllocateMemSpace(
ULONG MemUpperBound,
ULONG MemLowerBound,
ULONG Bus
)
{
ULONG i;
ULONG j;
ULONG MemBase;
PSPACE_DESC pSpace;
DEBUGMSG(ZONE_FUNCTION, (TEXT("AllocateMem %d %X %X\r\n"), Bus, MemUpperBound,MemLowerBound));
//
// Sort the space descriptors for a given bus by size
//
for (i = 31; i >= 1; i--) {
for (j = 0; j < nSpaceDesc; j++) {
pSpace = &SpaceDesc[j];
if ((pSpace->Bus == Bus) && ((pSpace->MemSize) & (1 << i))) {
if (pSpace->Bridge == 0) {
MemUpperBound -= pSpace->MemSize;
PCIConfig_Write(pSpace->Bus,
pSpace->Device,
pSpace->Function,
pSpace->Offset,
MemUpperBound);
pSpace->MemBase = MemUpperBound;
pSpace->SortOrder = SortOrder++;
DEBUGMSG(ZONE_INFO, (TEXT("AllocateMem %d %d %d %x %x (%X)\r\n"),
pSpace->Bus, pSpace->Device,
pSpace->Function, pSpace->Offset,
MemUpperBound,pSpace->MemSize));
} else {
if (!PciInitAllocateMemSpace(
MemUpperBound,
MemUpperBound - pSpace->MemSize,
pSpace->SecondaryBus)) {
return(FALSE);
}
//
// Init mem base and limit registers
//
((PBRIDGE_MEM)(&MemBase))->MemoryLimit.Address =
(WORD)(((MemUpperBound - 1) & 0xFFF00000) >> 20);
//((PBRIDGE_MEM)(&MemBase))->MemoryLimit.DecodeType = Something;
MemUpperBound -= pSpace->MemSize;
((PBRIDGE_MEM)(&MemBase))->MemoryBase.Address =
(WORD)(((MemUpperBound) & 0xFFF00000) >> 20);
//((PBRIDGE_MEM)(&MemBase))->MemoryBase.DecodeType = Something;
DEBUGMSG(ZONE_INFO, (TEXT("AllocateMemLimit %d %d %d %x %x (%X)\r\n"),
pSpace->Bus, pSpace->Device,
pSpace->Function, pSpace->Offset,
MemBase,pSpace->MemSize));
PCIConfig_Write(pSpace->Bus,
pSpace->Device,
pSpace->Function,
PCIBRIDGE_MEMORY,
MemBase);
pSpace->MemBase = MemBase;
pSpace->SortOrder = SortOrder++;
}
}
if (MemUpperBound < MemLowerBound) {
return(FALSE);
}
}
}
return(TRUE);
}
VOID
PciInitListDevices(
)
{
ULONG i,j;
DEBUGMSG(ZONE_PCICNFG, (TEXT("\n\rList of Detected PCI Devices")));
DEBUGMSG(ZONE_PCICNFG, (TEXT("\n\r-----------------------------------------------------------\n\r")));
for (i = 0; i < nDev; i++) {
// PrintVendorString(pDev[i].VendorID);
DEBUGMSG(ZONE_PCICNFG, (TEXT("\r\n")));
DEBUGMSG(ZONE_PCICNFG, (TEXT(" Bus:%d Dev:%d Funct:%d Class:%X IRQ:%X "),
pDev[i].Bus,
pDev[i].Device,
pDev[i].Function,
PCIConfig_Read(pDev[i].Bus,
pDev[i].Device,
pDev[i].Function,
PCI_CONFIG_CLASS_REVISION),
PCIConfig_Read(pDev[i].Bus,
pDev[i].Device,
pDev[i].Function,
PCI_CONFIG_INTERRUPT) & 0xff));
DEBUGMSG(ZONE_PCICNFG, (TEXT("\r\n")));
if ( PCIConfig_Read(pDev[i].Bus,
pDev[i].Device,
pDev[i].Function,
PCI_CONFIG_HEAD) & 0x00010000) {
DEBUGMSG(ZONE_PCICNFG, (TEXT("BARs %X %X MemBase: %X IoBase: %X"),
PCIConfig_Read(pDev[i].Bus,
pDev[i].Device,
pDev[i].Function,
PCI_CONFIG_BASE0),
PCIConfig_Read(pDev[i].Bus,
pDev[i].Device,
pDev[i].Function,
PCI_CONFIG_BASE1),
PCIConfig_Read(pDev[i].Bus,
pDev[i].Device,
pDev[i].Function,
PCIBRIDGE_MEMORY),
PCIConfig_Read(pDev[i].Bus,
pDev[i].Device,
pDev[i].Function,
PCIBRIDGE_IO)));
} else {
DEBUGMSG(ZONE_PCICNFG, (TEXT("BARs:")));
for (j = PCI_CONFIG_BASE0; j <= PCI_CONFIG_BASE5; j += 4 ) {
DEBUGMSG(ZONE_PCICNFG, (TEXT(" %X"),
PCIConfig_Read(pDev[i].Bus,
pDev[i].Device,
pDev[i].Function,
j)));
}
}
DEBUGMSG(ZONE_PCICNFG, (TEXT("\n\r\n\r")));
}
DEBUGMSG(ZONE_PCICNFG, (TEXT("Bus Dev Fnct Off MemBase MemSize IoBase IoSize\r\n")));
for (i = 0; i < SortOrder; i++) {
for (j = 0; j < nSpaceDesc; j++) {
if (SpaceDesc[j].SortOrder == i) {
DEBUGMSG(ZONE_PCICNFG, (TEXT("%B %B %B %B %X %X %X %X\r\n"),
SpaceDesc[j].Bus,
SpaceDesc[j].Device,
SpaceDesc[j].Function,
SpaceDesc[j].Offset,
SpaceDesc[j].MemBase,
SpaceDesc[j].MemSize,
SpaceDesc[j].IoBase,
SpaceDesc[j].IoSize));
}
}
}
}
BOOL
PciInitSearchForDevice(
ULONG VendorID,
PULONG Bus,
PULONG Device,
PULONG Function
)
{
ULONG i;
for (i = 0; i < nDev; i++) {
if (pDev[i].VendorID == VendorID) {
*Bus = pDev[i].Bus;
*Device = pDev[i].Device;
*Function = pDev[i].Function;
return(TRUE);
}
}
return(FALSE);
}
BOOL PCIInitListDevicesSummary(void)
{
UCHAR nCount=0;
PCI_DEVICE *p=NULL;
DEBUGMSG(ZONE_PCICNFG, (TEXT("\r\nPCI Device List:\r\n")));
DEBUGMSG(ZONE_PCICNFG, (TEXT("----------------------------------------------------------------------------\r\n")));
DEBUGMSG(ZONE_PCICNFG, (TEXT(" VenId DevId (B:D:F) BAR0 Stat/Cmd Class/ID\r\n")));
DEBUGMSG(ZONE_PCICNFG, (TEXT("----------------------------------------------------------------------------\r\n")));
for(nCount=0 ; nCount < MAX_DEVICE ; nCount++)
{
p=&pDev[nCount];
if(!p->VendorID)
break;
DEBUGMSG(ZONE_PCICNFG, (TEXT("%X %X (%d:%d:%d) 0x%X 0x%X 0x%X\r\n"),
(p->VendorID&0xFFFF), (p->VendorID&0xFFFF0000)>>16,
p->Bus, p->Device, p->Function,
PCIConfig_Read(p->Bus, p->Device, p->Function, 0x10),
PCIConfig_Read(p->Bus, p->Device, p->Function, 0x04),
PCIConfig_Read(p->Bus, p->Device, p->Function, 0x08)));
}
return(TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -