?? dec2155xcpci.c
字號:
/* examine each bit to determine which bit(s) is set */ for (vecNum = DEC2155X_DOORBELL0_INT_VEC; vecNum <= DEC2155X_DOORBELL15_INT_VEC; vecNum++) { if (status & mask) { if ((currHandler = sysIntTbl[vecNum]) == NULL) logMsg ("uninitialized Dec2155x interrupt %d\n", vecNum, 0,0,0,0,0); else { while (currHandler != NULL) { currHandler->vec (currHandler->arg); currHandler = currHandler->next; } } } /* advance to next bit */ mask <<= 1; } } /* check for I2O event */ intMskAdrs = DEC2155X_CSR_ADRS(DEC2155X_CSR_I2O_IBND_PST_LST_MSK); intClrAdrs = DEC2155X_CSR_ADRS(DEC2155X_CSR_I2O_IBND_PST_LST_STS); mask = ~(sysPciInWord (intMskAdrs)); status = sysPciInWord (intClrAdrs) & DEC2155X_I2O_PST_LST_MSK; if (status & mask) { /* clear interrupt source */ sysPciOutWordConfirm (intClrAdrs, status); vecNum = DEC2155X_I2O_INT_VEC; if ((currHandler = sysIntTbl[vecNum]) == NULL) logMsg ("uninitialized Dec2155x interrupt %d\n", vecNum, 0,0,0,0,0); else { while (currHandler != NULL) { currHandler->vec (currHandler->arg); currHandler = currHandler->next; } } } /* * check for Upstream Memory 2 Page Crossing event starting with the * first 32 bits, followed by the next 32 bits. */ intMskAdrs = DEC2155X_CSR_ADRS(DEC2155X_CSR_US_PG_BND_IRQ_MSK0); intClrAdrs = DEC2155X_CSR_ADRS(DEC2155X_CSR_US_PG_BND_IRQ0); status = sysPciInWord (intClrAdrs) & ~(sysPciInWord (intMskAdrs)); intMskAdrs = DEC2155X_CSR_ADRS(DEC2155X_CSR_US_PG_BND_IRQ_MSK1); intClrAdrs = DEC2155X_CSR_ADRS(DEC2155X_CSR_US_PG_BND_IRQ1); /* re-use the mask variable to hold the status for the upper 32 bits */ mask = sysPciInWord (intClrAdrs) & ~(sysPciInWord (intMskAdrs)); if (status || mask) { vecNum = DEC2155X_PG_CRSSNG_INT_VEC; if ((currHandler = sysIntTbl[vecNum]) == NULL) { logMsg ("uninitialized Dec2155x interrupt %d\n", vecNum, 0,0,0,0,0); /* since there is no registered handler, clear interrupt source */ sysPciOutWordConfirm (intClrAdrs, mask); intClrAdrs = DEC2155X_CSR_ADRS(DEC2155X_CSR_US_PG_BND_IRQ0); sysPciOutWordConfirm (intClrAdrs, status); } else { /* isr handles interrupt clearing */ while (currHandler != NULL) { currHandler->vec (currHandler->arg); currHandler = currHandler->next; } } } return; }/******************************************************************************** sysDec2155xCnvrtAdrs - converts an address across the Dec2155x** This routine examines the caller-provided array of Dec2155x windows looking* for a window which maps the target address. If such a window is found, the* caller's address is converted to the equivalent address as it would appear* on the opposite bus.** RETURNS: OK if conversion successful, else ERROR.** SEE ALSO: sysLocalToBusAdrs(), sysBusToLocalAdrs(), sysDec2155xCnvrtAdrs()*/LOCAL STATUS sysDec2155xCnvrtAdrs ( UINT32 adrsSpace, UINT32 adrs, UINT32 *pCnvrtAdrs, UINT32 winCnt, WINDOW_PARAMETERS *pWinParam ) { while (winCnt--) { if ( (pWinParam->windowType == adrsSpace) && (adrs >= pWinParam->trgtBase) && (adrs <= pWinParam->trgtLimit) ) { *pCnvrtAdrs = ( adrs - pWinParam->trgtBase + pWinParam->origBase ); return (OK); }; pWinParam++; } /* * no window was found to contain adrs. indicate that translation was * not possible. */ return (ERROR); }/******************************************************************************** sysDec2155xCaptWindows - captures Dec2155x window configuration** This routine searches through either the upstream or downstream Dec2155x* windows and captures the information required by the sysDec2155xCnvrtAdrs* routine. ** NOTE: This routine should not be called until the responsible processor has* enumerated the PCI bus. This is assured by checking the status of the* enable bits in the Primary and Secondary PCI command registers.** RETURNS: N/A** SEE ALSO: sysLocalToBusAdrs(), sysBusToLocalAdrs(), sysDec2155xCnvrtAdrs()*/LOCAL void sysDec2155xCaptWindows ( UINT32 winCnt, WINDOW_OFFSETS *pWinOffsets, WINDOW_PARAMETERS *pWinParam, UINT32 *winsValid ) { UINT32 bar; /* holds contents of base address register */ UINT32 mask; /* holds mask used to isolate valid bits translation reg */ UINT32 trans; /* value used to convert between address spaces */ *winsValid = 0; while (winCnt--) { /* read setup register offset from the offset table. */ mask = pWinOffsets->setup; /* * if the setup value from the table is an offset, then read the setup * register. if the value from the table is a default setup value * (indicates no setup register for this bar), then just use it as is. */ if ( !(mask & DEC2155X_SETUP_REG_BAR_ENABLE) ) DEC2155X_CFG_RD_LONG(mask, &mask); /* see if the register is enabled */ if ( mask & DEC2155X_SETUP_REG_BAR_ENABLE ) { /* * determine which PCI space the register is in (memory or i/o). * and, setup the window type. adjust the mask to eliminate * reserved bits from the setup register. */ if ( (mask & PCI_BAR_SPACE_MASK) == PCI_BAR_SPACE_MEM ) { pWinParam->windowType = PCI_BAR_SPACE_MEM; mask &= ~DEC2155X_MEM_TB_RSV_MSK; } else { pWinParam->windowType = PCI_BAR_SPACE_IO; mask &= ~DEC2155X_IO_OR_MEM_TB_RSV_MSK; } /* read the remaining register contents */ DEC2155X_CFG_RD_LONG(pWinOffsets->bar, &bar); DEC2155X_CFG_RD_LONG(pWinOffsets->trans, &trans); /* remove unused bits */ bar &= mask; trans &= mask; /* * save the base address of the window as seen from the originating * and target sides. calculate limit of the window as seen from * the target side. */ pWinParam->origBase = bar + pWinOffsets->unuseable; pWinParam->trgtBase = trans + pWinOffsets->unuseable; pWinParam->trgtLimit = trans + ~mask; if ( pWinParam->trgtLimit > pWinParam->trgtBase ) { (*winsValid)++; pWinParam++; } /* advance to next window */ pWinOffsets++; } else { /* * pci base address registers must be contiguous, first disabled * register terminates the loop. */ break; } } }/******************************************************************************** sysDec2155xChkEnables - check the originating and target bus enables** This routine examines the states of the I/O or Memory enables on the* originating bus and the Master Enable on the target bus. Both must be* enabled before the Dec2155x can pass a transaction across to the opposite* bus.** RETURNS: OK if the bridge is active, else ERROR** SEE ALSO: sysLocalToBusAdrs(), sysBusToLocalAdrs(), sysDec2155xCnvrtAdrs()*/STATUS sysDec2155xChkEnables (UINT32 origOffset, UINT32 trgtOffset, UINT32 adrsSpace ) { UINT16 cmdReg; UINT16 mask; /* first determine if the required originating side enable is active */ switch (adrsSpace) { case PCI_BAR_SPACE_MEM: mask = PCI_CMD_MEM_ENABLE; break; case PCI_BAR_SPACE_IO: mask = PCI_CMD_IO_ENABLE; break; default: mask = 0; break; } /* read the PCI command register as seen from the originating side */ DEC2155X_CFG_RD_WORD(origOffset, &cmdReg); if ( !(cmdReg & mask) ) return (ERROR); /* access not enabled */ /* now determine if the target side bus master enable is set */ DEC2155X_CFG_RD_WORD(trgtOffset, &cmdReg); if (cmdReg & PCI_CMD_MASTER_ENABLE) return (OK); else return (ERROR); } /******************************************************************************** sysPciToCpciAdrs - convert a local PCI address to a Compact PCI bus address** Given a local PCI address, this routine returns the corresponding Compact PCI* address provided that such an address exists. The translation is performed by* examining downstream windows in sequence until a window is found which* contains the specified local address. The translation is then performed using * the base addresses of the window as viewed from the local PCI and Compact PCI* bus sides.*** RETURNS: OK, or ERROR if the address space is unknown or the mapping is not* possible.** SEE ALSO: sysCpciToPciAdrs(), sysDec2155xCaptWindows(),* sysDec2155xCnvrtAdrs()*/LOCAL STATUS sysPciToCpciAdrs ( int adrsSpace, /* bus address space where busAdrs resides */ char * localAdrs, /* bus address to convert */ char ** pBusAdrs /* where to return bus address */ ) { /* * before a downstream window can be operational, the host processor must * have enabled the dec2155x memory and/or i/o access in the PCI primary * command register and the local processor must have enabled the bus * master bit in the secondary PCI command register. before proceeding, * verify that the required access is enabled */ if ( sysDec2155xChkEnables (PCI_CFG_COMMAND + DEC2155X_PRI_FROM_SEC_OFFSET, PCI_CFG_COMMAND, adrsSpace) != OK ) return (ERROR); /* if the downstream windows array is un-initialized, go initialize it */ if (dsWindows[0].trgtLimit == 0) sysDec2155xCaptWindows (DS_WINDOW_COUNT, &dsWindowOffsets[0], &dsWindows[0], &dsWinsValid); /* convert a local pci address to a compact pci address */ return ( sysDec2155xCnvrtAdrs (adrsSpace, (UINT32)localAdrs, (UINT32 *)pBusAdrs, dsWinsValid, &dsWindows[0]) ); }/******************************************************************************** sysCpciToPciAdrs - convert a compact pci bus address to a local pci address** Given a Compact PCI address, this routine returns the corresponding local PCI* address provided that such an address exists. The translation is performed by* examining the upstream windows in sequence until a window is found which* contains the specified Compact PCI bus address. The translation is then* performed using the base addresses of the window as viewed from the bus and* local sides. ** RETURNS: OK, or ERROR if the address space is unknown or the mapping is not* possible.** SEE ALSO: sysPciToCpciAdrs(), sysDec2155xCaptWindows(),* sysDec2155xCnvrtAdrs()*/LOCAL STATUS sysCpciToPciAdrs ( int adrsSpace, /* bus address space where busAdrs resides */ char * busAdrs, /* bus address to convert */ char ** pLocalAdrs /* where to return local address */ ) { /* * before an upstream window can be operational, the local processor must * have enabled the dec2155x memory and/or i/o spaces in the PCI secondary * command register and the host processor must have enabled the bus * master bit in the primary PCI command register. before proceeding * verify that the required access is enabled. */ if ( sysDec2155xChkEnables (PCI_CFG_COMMAND, PCI_CFG_COMMAND + DEC2155X_PRI_FROM_SEC_OFFSET, adrsSpace) != OK ) return (ERROR); /* if the upstream windows array is un-initialized, go initialize it */ if (usWindows[0].trgtLimit == 0) sysDec2155xCaptWindows (US_WINDOW_COUNT, &usWindowOffsets[0], &usWindows[0], &usWinsValid); /* convert a compact pci address to a local pci address */ return ( sysDec2155xCnvrtAdrs (adrsSpace, (UINT32)busAdrs, (UINT32 *)pLocalAdrs, usWinsValid, &usWindows[0]) ); }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -