📄 tyspci.c
字号:
} /* Post-configure 32-bit Non-prefetchable Memory Limit Address */ if ((pSystem->pciMemIo32Size) > 0) { temp = (pSystem->pciMemIo32); (pSystem->pciMemIo32) = (((pSystem->pciMemIo32) & ~0xfffff) + 0x100000); (pSystem->pciMemIo32Size) -= ((pSystem->pciMemIo32) - temp); printf("NP Mem Lim: orig[0x%08x] new[0x%08x] adj[0x%08x]\n",
temp, pSystem->pciMemIo32,
(pSystem->pciMemIo32) - temp );
pciConfigModifyLong (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_MEM_BASE, 0xfff00000, (pSystem->pciMemIo32 - 1) ); pciConfigInLong (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_MEM_BASE, &debugTmp2); debugTmp = (debugTmp2 & 0xfff00000); debugTmp |= 0x000FFFFF; printf("pciAutoBusConfig: Mem Limit [0x%08x]\n",
debugTmp);
} /* Post-configure 32-bit Prefetchable Memory Address */ if ( (pPciLoc->attribute & PCI_AUTO_ATTR_BUS_PREFETCH) && ((pSystem->pciMem32Size) > 0) ) { temp = (pSystem->pciMem32); (pSystem->pciMem32) = (((pSystem->pciMem32) & ~0xfffff) + 0x100000); (pSystem->pciMem32Size) -= ((pSystem->pciMem32) - temp); printf("PF Mem Lim: orig[0x%08x] new[0x%08x] adj[0x%08x]\n",
temp, pSystem->pciMem32,
(pSystem->pciMem32) - temp
); /* 64-bit Prefetchable memory not supported at this time */ pciConfigOutLong (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_PRE_MEM_LIMIT_U, 0); pciConfigModifyLong (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_PRE_MEM_BASE, 0xfff00000, (pSystem->pciMem32 - 1) ); pciConfigInLong (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_PRE_MEM_BASE, &debugTmp2); debugTmp = (debugTmp2 & 0xfff00000); debugTmp |= 0x000FFFFF; printf("pciAutoBusConfig: PF Mem Limit [0x%08x]\n",
debugTmp);
} if ((pSystem->bridgePostConfigInit) != NULL ) { pciConfigInLong (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_VENDOR_ID, &dev_vend); (pSystem->bridgePostConfigInit) (pSystem, pPciLoc, dev_vend); } /* Initialize primary and secondary PCI-PCI bridge latency timers */ pciConfigOutByte (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_SEC_LATENCY, pSystem->maxLatency); /* Clear status bits turn on downstream and upstream (master) mem,IO */ pciConfigOutLong (pPciLoc->bus, pPciLoc->device, pPciLoc->function, PCI_CFG_COMMAND, (UINT32)(0xffff0000 | PCI_CMD_IO_ENABLE | PCI_CMD_MEM_ENABLE | PCI_CMD_MASTER_ENABLE) ); }
LOCAL UINT tysAutoMemAlloc
( PCI_SYSTEM * pPciSys, /* PCI system structure */ PCI_LOC * pPciFunc, /* Pointer to PCI function element */ UINT * pAlloc, /* Pointer to PCI space alloc pointer */ UINT size, /* space requested (power of 2) */ UINT addrInfo /* PCI address type information */ ) { UINT register64Bit = 0; /* 64 bit register flag */ UINT * pBase; UINT * pAvail; UINT addr; /* Handle non-prefetchable PCI Memory (pciMemIo32) */ if ( ((addrInfo & (UINT)PCI_BAR_MEM_PREFETCH) != 0) && (((pPciFunc->attribute) & PCI_AUTO_ATTR_BUS_PREFETCH) != 0 ) ) { printf("pciAutoMemAlloc: PF Mem req\n");
pBase = &(pPciSys->pciMem32); pAvail = &(pPciSys->pciMem32Size); } else { pBase = &(pPciSys->pciMemIo32); pAvail = &(pPciSys->pciMemIo32Size); } switch (addrInfo & (UINT)PCI_BAR_MEM_TYPE_MASK ) { case PCI_BAR_MEM_BELOW_1MB: break; case PCI_BAR_MEM_ADDR64: /* * Check for a 64-bit addressable memory device, currently * the PReP address map does not support physical addresses * above 4Gb (i.e., 32-bits), so the configuration process * will initialize the upper base register to zero (i.e., * the safe thing to do), so for right now we'll skip the * next base address register which belongs to the 64-bit * pair of 32-bit base address registers. */ register64Bit = 1; break; case PCI_BAR_MEM_ADDR32: break; case PCI_BAR_MEM_RESERVED: /* fall through */ default: *pAlloc = NO_ALLOCATION; return 0; } /* Allocation */ /* Adjust for alignment */ size -= 1; addr = ((*pBase + size) & ~size); size += ((addr - *pBase) + 1); if (size > *pAvail) { if ((addrInfo & (UINT)PCI_BAR_MEM_PREFETCH) != 0) { /* If no PF memory available, then try conventional */ pBase = &(pPciSys->pciMemIo32); pAvail = &(pPciSys->pciMemIo32Size); size -= 1; addr = ((*pBase + size) & ~size); size += ((addr - *pBase) + 1); if (size > *pAvail) { logMsg("Warning: PCI PF Mem alloc failed\n", 0, 0, 0, 0, 0, 0); addr = NO_ALLOCATION; size = 0; } } /* if space is exhausted, then return an invalid pointer */ logMsg("Warning: PCI Memory allocation failed\n", 0, 0, 0, 0, 0, 0); addr = NO_ALLOCATION; size = 0; } printf("pciAutoMemAlloc: \n");
printf(" Pre: pBase[0x%08x], pAvail[0x%08x]\n",
(int)(*pBase), (int)(*pAvail));
*pAlloc = addr; *pBase += size; *pAvail -= size; printf(" Post: pBase[0x%08x], pAvail[0x%08x]\n",
(int)(*pBase), (int)(*pAvail));
return register64Bit; }
LOCAL UCHAR sysPciIntRoute [NUM_PCI_SLOTS][3] =
{ {PCI_XINT1_LVL, PCI_XINT3_LVL, PCI_XINT2_LVL}, /* slot 1 */
{PCI_XINT2_LVL, PCI_XINT1_LVL, PCI_XINT3_LVL}, /* slot 2 */
{PCI_XINT3_LVL, PCI_XINT2_LVL, PCI_XINT1_LVL}, /* slot 3 */};
LOCAL UINT tysAutoIoAlloc
( PCI_SYSTEM * pPciSys, /* PCI system structure */ PCI_LOC *pPciFunc, /* input: Pointer to PCI function element */ UINT *pAlloc, /* output: Pointer to PCI space alloc pointer */ UINT nSize /* requested size (power of 2) */ ) { UINT * pBase; UINT addr; UINT * pAvail = NULL; /* Assign this register to PCI I/O space */ if ((pPciFunc->bus == 0) && ((pPciFunc->attribute & PCI_AUTO_ATTR_BUS_4GB_IO) != 0)) { printf("pciAutoIoAlloc: 32-bit I/O\n");
pBase = &(pPciSys->pciIo32); pAvail = &(pPciSys->pciIo32Size); } else { printf("pciAutoIoAlloc: 16-bit I/O\n");
pBase = &(pPciSys->pciIo16); pAvail = &(pPciSys->pciIo16Size); } /* Adjust for alignment */ nSize -= 1; addr = ((*pBase + nSize) & ~nSize); nSize += (addr - *pBase + 1); /* If the space is exhausted, then return an invalid pointer */ if (nSize > *pAvail) { logMsg("Warning: PCI I/O allocation failed\n", 0, 0, 0, 0, 0, 0); addr = NO_ALLOCATION; nSize = 0; } printf("pciAutoIoAlloc: Pre/Post alloc: \n");
printf(" Pre: pBase[0x%08x], pAvail[0x%08x]\n",
(int)(*pBase), (int)(*pAvail));
*pAlloc = addr; *pBase += nSize; *pAvail -= nSize; printf(" Post: pBase[0x%08x], pAvail[0x%08x]\n",
(int)(*pBase), (int)(*pAvail));
return 0; /* can't have 64 bit i/o addresses */ }
LOCAL UINT tysAutoRegConfig
( PCI_SYSTEM * pSystem, /* Pointer to PCI System structure */ PCI_LOC *pPciFunc, /* Pointer to function in device list */ UINT baseAddr, /* Offset of base PCI address */ UINT nSize, /* Size and alignment requirements */ UINT addrInfo /* PCI address type information */ ) { UINT addr; /* Working address variable */ UINT spaceEnable = 0; /* PCI space enable bit */ UINT baseaddr_mask; /* Mask for base address register */ UINT register64Bit; /* 64 bit register flag */ /* Select the appropriate PCI address space for this register */ if ((addrInfo & PCI_BAR_SPACE_MASK) == PCI_BAR_SPACE_IO) { /* Configure this register for PCI I/O space */ spaceEnable = PCI_CMD_IO_ENABLE; baseaddr_mask = 0xFFFFFFFC; register64Bit = tysAutoIoAlloc (pSystem, pPciFunc, &addr, nSize);
} else { /* Configure this register for PCI memory space */ spaceEnable = PCI_CMD_MEM_ENABLE; baseaddr_mask = 0xFFFFFFF0; register64Bit = tysAutoMemAlloc (pSystem, pPciFunc, &addr, nSize,
addrInfo); } /* * Do not exceed the upper boundary! If this occurs, all we can * do here is return, as this is called early in the initialization * process, before I/O is available to print error messages. */ if (addr != NO_ALLOCATION) { /* Program the base address register */ printf("pciAutoRegConfig:[0x%08x] written to BAR[0x%08x]\n",
addr, baseAddr);
pciConfigModifyLong (pPciFunc->bus, pPciFunc->device, pPciFunc->function, baseAddr, baseaddr_mask, addr); if (register64Bit) { /* * Write the base address for 64-bit addressable memory devices: * initialize the next base address register to zero, the PReP * address map does support physical addresses above 4GB (i.e., * 32-bit address space) */ pciConfigOutLong (pPciFunc->bus, pPciFunc->device, pPciFunc->function, baseAddr + 4, 0); } /* Set the appropriate enable bit, preserve status bits */ pciConfigModifyLong (pPciFunc->bus, pPciFunc->device, pPciFunc->function, PCI_CFG_COMMAND, (0xffff0000 | spaceEnable), spaceEnable); } return (register64Bit); }
LOCAL void tysAutoFuncDisable
( PCI_LOC *pPciFunc /* input: Pointer to PCI function struct */ ) { UCHAR cTemp; /* Temporary storage */ UINT16 wTemp; if ((pPciFunc->attribute) & PCI_AUTO_ATTR_DEV_EXCLUDE) { return; } printf("pciAutoFuncDisable: disable device [%d,%d,%d,0x%02x]\n",
pPciFunc->bus,
pPciFunc->device,
pPciFunc->function,
pPciFunc->attribute );
/* Disable Memory, I/O, and Bus Mastering, save status bits */ wTemp = (PCI_CMD_IO_ENABLE | PCI_CMD_MEM_ENABLE | PCI_CMD_MASTER_ENABLE ); pciConfigModifyLong (pPciFunc->bus, pPciFunc->device, pPciFunc->function, PCI_CFG_COMMAND, (0xffff0000 | wTemp), 0x0); /* Disable header dependent fields */ pciConfigInByte (pPciFunc->bus, pPciFunc->device, pPciFunc->function, PCI_CFG_HEADER_TYPE, &cTemp); cTemp &= PCI_HEADER_TYPE_MASK; switch (cTemp) { case PCI_HEADER_TYPE0: /* non PCI-PCI bridge */ /* * Disable Expansion ROM address decode for the device. * Note that no mem space is allocated for the Expansion * ROM, so a re-enable later should NOT be done. */ pciConfigModifyLong (pPciFunc->bus, pPciFunc->device, pPciFunc->function, PCI_CFG_EXPANSION_ROM, 0x1, 0); break; case PCI_HEADER_PCI_PCI: /* PCI-PCI bridge */ pciConfigModifyLong (pPciFunc->bus, pPciFunc->device, pPciFunc->function, PCI_CFG_ROM_BASE, 0x1, 0); break; default: break; } return; }
LOCAL void tysAutoFuncConfig
( PCI_SYSTEM * pSystem, PCI_LOC * pPciFunc /* input: "Include list" pointer to function */ ) { UINT baMax; /* Total number of base addresses */ UINT baI; /* Base address register index */ UINT baseAddr; /* PCI Offset of base address */ UINT readVar; /* Contents of base address register */ UINT addrInfo; /* PCI address type information */ UINT sizeMask; /* LSbit for size calculation */ UCHAR headerType; /* Read from PCI config header */ UINT dev_vend; /* If there is a function, then consult the exclusion routine */ if ( (pSystem->includeRtn) != NULL ) { pciConfigInLong (pPciFunc->bus, pPciFunc->device, pPciFunc->function, PCI_CFG_VENDOR_ID, &dev_vend); if ( ((pSystem->includeRtn) (pSystem, pPciFunc, dev_vend)) == ERROR ) { if ((pPciFunc->attribute & PCI_AUTO_ATTR_BUS_PCI) == 0) { pPciFunc->attribute |= PCI_AUTO_ATTR_DEV_EXCLUDE; printf("pciAutoFuncConfig: exc [%d,%d,%d,0x%02x]\n",
pPciFunc->bus, pPciFunc->device, pPciFunc->function, pPciFunc->attribute);
return; } } } /* Disable the function */ tysAutoFuncDisable (pPciFunc);
/* Determine the number of base address registers present */ pciConfigInByte (pPciFunc->bus, pPciFunc->device, pPciFunc->function, PCI_CFG_HEADER_TYPE, &headerType); headerType &= 0x7f; switch (headerType) { case PCI_HEADER_TYPE0: baMax = 6; break; case PCI_HEADER_PCI_PCI: baMax = 2; break; default: baMax = 0; break; } /* Allocate Memory or I/O space for each implemented base addr register */ for (baI = 0; baI < baMax; baI++) { /* Get the base address register contents */ baseAddr = PCI_CFG_BASE_ADDRESS_0 + (baI * 4); pciConfigOutLong (pPciFunc->bus, pPciFunc->device, pPciFunc->function, baseAddr, 0xFFFFFFFF); pciConfigInLong (pPciFunc->bus, pPciFunc->device, pPciFunc->function, baseAddr, &readVar); /* Stop looking when an unimplemented BAR (BAR==0) is found */ if (readVar == 0) { break; } /* Mask off all but space, memory type, and prefetchable bits */ addrInfo = readVar & PCI_BAR_ALL_MASK; /* Check for type, setup mask variables (based on type) */ if ((addrInfo & PCI_BAR_SPACE_MASK) == PCI_BAR_SPACE_IO) { printf("pciAutoFuncConfig: IO Space found at BAR[%d]\n",
baI);
sizeMask = (1 << 2); } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -