📄 syslib.c
字号:
* identical length windows but one will be the PCI-bus view * of the address base and limit and the other will be the * CPU-based view of the address base and limit. When a * sysBusToLocalAdrs() call is eventually made with an address * which falls within the mapping of this inbound address * window, the two arrays will be queried to perform the * associated address translation. * * In a similar fashion, after all the inbound windows are * queried and associated entries made in the two above-mentioned * arrays, the outbound windows will be queried and associated * entries again made first in sysHarrierCpuToPciWin[] and * next in sysHarrierPciToCpuWin[]. */ /* initialize number of valid windows found */ sysValidHarrierWindows = 0; /* point to window save arrays */ pHarrierCpu = &sysHarrierCpuToPciWin[0]; pHarrierPci = &sysHarrierPciToCpuWin[0]; /* start with the cpu to pci windows (ppc slaves) */ pHarrierOffO = &sysHarrierCpuWinOff[0]; /* loop through each window */ for (index = 0; index < HARRIER_CPU_WIN_CNT; index++) { /* read the window attributes */ attr = * (UINT16 *) (pHarrierOffO->attr); attr &= HARRIER_PCFS_OTAT_ENA_MASK; if (attr & HARRIER_PCFS_OTAT_ENA) { /* active window found, bump valid window counter */ sysValidHarrierWindows++; /* determine the window type (memory or i/o) */ pHarrierCpu->winType = (attr & HARRIER_PCFS_OTAT_MEM) ? PCI_BAR_SPACE_MEM : PCI_BAR_SPACE_IO; /* * Outbound window 3 requires special handling since it is * always I/O space. */ if (pHarrierOffO->range == HARRIER_OUTBOUND_TRANSLATION_ADDR_3_REG) pHarrierCpu->winType = PCI_BAR_SPACE_IO; pHarrierPci->winType = pHarrierCpu->winType; /* read the window range */ range = * (UINT32 *) (pHarrierOffO->range); trans = * (UINT16 *) (pHarrierOffO->offset); pHarrierCpu->winBase = range & ~0xffff; pHarrierCpu->winLimit = (range << 16) | 0xffff; /* calculate translated values */ pHarrierPci->winBase = pHarrierCpu->winBase + (trans << 16); pHarrierPci->winLimit = pHarrierCpu->winLimit + (trans << 16); /* advance in preparation for next valid window */ pHarrierCpu++; pHarrierPci++; } /* advance to next set of harrier offsets */ pHarrierOffO++; } /* switch to harrier pci to cpu windows (pci slaves) */ pHarrierOffI = &sysHarrierPciWinOff[0]; /* loop through each window */ for (index = 0; index < HARRIER_PCI_WIN_CNT; index++) { /* read the window attributes */ attr = * (UINT32 *) (pHarrierOffI->attr); if (attr & HARRIER_ITAT_ENA) { /* active window found, bump valid window counter */ sysValidHarrierWindows++; /* set the window type to memory or I/O based on MEM bit setting */ if (attr & HARRIER_ITAT_MEM) pHarrierCpu->winType = PCI_BAR_SPACE_MEM; else pHarrierCpu->winType = PCI_BAR_SPACE_IO; pHarrierPci->winType = pHarrierCpu->winType; /* read the window base */ base = sysPciInLong (pHarrierOffI->base); base = base & ~0xf; size = sysPciInByte (pHarrierOffI->size); size = 0x1000 << size; /* Convert code to real size */ offset = sysPciInWord(pHarrierOffI->offset); offset = offset << 16; /* isolate the window base (start) and limit (end) */ pHarrierPci->winBase = base & ~0xf; pHarrierPci->winLimit = base + size - 1; /* calculate translated values */ pHarrierCpu->winBase = (pHarrierPci->winBase & 0x0000ffff) | offset; pHarrierCpu->winLimit = pHarrierCpu->winBase + size - 1; /* advance in preparation for next valid window */ pHarrierCpu++; pHarrierPci++; } /* advance to next set of harrier offsets */ pHarrierOffI++; } }/******************************************************************************** sysHarrierTransAdrs - translate an address that passes through the harrier.** This routine converts an address from a cpu to pci address or vice versa. It* uses a pair of window arrays built during hardware init2 to guide the* translation. The adrs parameter is the address to convert.** RETURNS: OK, or ERROR if the address space is unknown or the mapping is not* possible.** SEE ALSO: sysHarrierCapt(), sysPciToCpuAdrs(), sysBusToLocalAdrs(), * sysLocalToBusAdrs(), and sysHarrierTransAdrs().**/LOCAL STATUS sysHarrierTransAdrs ( UINT32 adrsSpace, /* address space (memory or i/o ) */ UINT32 adrs, /* known address */ UINT32 * pTransAdrs, /* pointer to the translated address */ UINT32 winCnt, /* number of open windows */ HARRIER_WIN_STRUCT * pSrc, /* pointer to the source windows */ HARRIER_WIN_STRUCT * pDest /* pointer to the destination windows */ ) { while (winCnt--) { /* check for a match on window type and in bounds */ if ( (pSrc->winType == adrsSpace) && (adrs >= pSrc->winBase) && (adrs <= pSrc->winLimit) ) { *pTransAdrs = ( adrs - pSrc->winBase + pDest->winBase ); return (OK); }; /* advance to next window */ pSrc++; pDest++; } /* * no window was found to contain adrs. indicate that translation was * not possible. */ return (ERROR); }/******************************************************************************** sysCpuToPciAdrs - translate a cpu address to a pci bus address** This routine converts an address as seen from the cpu to the equivalent pci* address, if it exists. The input address is the address as seen by the cpu.** RETURNS: OK, or ERROR if the address space is unknown or the mapping is not* possible.** * SEE ALSO: sysPciToCpuAdrs(), sysBusToLocalAdrs(), sysLocalToBusAdrs()* sysHarrierCapt(), and sysHarrierTransAdrs().*/LOCAL STATUS sysCpuToPciAdrs ( int adrsSpace, /* bus address space where busAdrs resides */ char * localAdrs, /* local address to convert */ char ** pBusAdrs /* where to return bus address */ ) { return (sysHarrierTransAdrs (adrsSpace, (UINT32)localAdrs, (UINT32 *)pBusAdrs, sysValidHarrierWindows, &sysHarrierCpuToPciWin[0], &sysHarrierPciToCpuWin[0]) ); }/******************************************************************************** sysPciToCpuAdrs - translate a pci bus address to a cpu address** This routine converts an address as seen from the pci bus to the equivalent* cpu address, if it exists. The input address is the address as seen by the* pci bus.** RETURNS: OK, or ERROR if the address space is unknown or the mapping is not* possible.** SEE ALSO: sysCpuToPciAdrs(), sysBusToLocalAdrs(), sysLocalToBusAdrs()* sysHarrierCapt(), and sysHarrierTransAdrs().*/LOCAL STATUS sysPciToCpuAdrs ( int adrsSpace, /* bus address space where busAdrs resides */ char * localAdrs, /* local address to convert */ char ** pBusAdrs /* where to return bus address */ ) { return (sysHarrierTransAdrs (adrsSpace, (UINT32)localAdrs, (UINT32 *)pBusAdrs, sysValidHarrierWindows, &sysHarrierPciToCpuWin[0], &sysHarrierCpuToPciWin[0]) ); }/******************************************************************************** sysLocalToBusAdrs - convert a local CPU address to a PCI bus address** Given a CPU address, this routine returns a corresponding local PCI bus* or Compact (backpanel) PCI bus address provided that such an address exists.* The target PCI bus (local or backpanel) is selected by the adrsSpace* parameter. Legal values for this parameter are found in "pci.h". If a* transparent bridge is used to access the Compact PCI bus, the local PCI bus* and the backpanel PCI bus share the same address space. In this case, the* local and backpanel address space designators are synonomous.** RETURNS: OK, or ERROR if the address space is unknown or the mapping is not* possible.** SEE ALSO: sysBusToLocalAdrs()*/STATUS sysLocalToBusAdrs ( int adrsSpace, /* bus address space where busAdrs resides */ char * localAdrs, /* local address to convert */ char ** pBusAdrs /* where to return bus address */ ) { switch (adrsSpace) { case PCI_SPACE_IO_PRI: case PCI_SPACE_IO_SEC: /* convert from cpu address space to local pci space */ if ( sysCpuToPciAdrs (PCI_BAR_SPACE_IO, localAdrs, pBusAdrs) != OK ) return (ERROR);#ifdef INCLUDE_DEC2155X /* * if continuing on to the backpanel using the dec2155x, translate * from local pci space to compact pci space. */ if ( PCI_SPACE_IS_CPCI(adrsSpace) ) return ( sysPciToCpciAdrs (PCI_BAR_SPACE_IO, *pBusAdrs, pBusAdrs) );#endif /* INCLUDE_DEC2155X */ break; case PCI_SPACE_MEMIO_PRI: case PCI_SPACE_MEM_PRI: case PCI_SPACE_MEMIO_SEC: case PCI_SPACE_MEM_SEC: /* convert from cpu address space to local pci address space */ if (sysCpuToPciAdrs (PCI_BAR_SPACE_MEM, localAdrs, pBusAdrs) != OK ) return (ERROR);#ifdef INCLUDE_DEC2155X /* * if continuing on to the backpanel using the dec2155x, translate * from local pci space to compact pci space. */ if ( PCI_SPACE_IS_CPCI(adrsSpace) ) return ( sysPciToCpciAdrs(PCI_BAR_SPACE_MEM, *pBusAdrs, pBusAdrs) );#endif /* INCLUDE_DEC2155X */ break; default: return (ERROR); } return (OK); }/******************************************************************************** sysBusToLocalAdrs - convert a PCI bus address to a local CPU address** Given a local or Compact (backpanel) PCI address, this routine returns a* corresponding local CPU bus address provided such an address exists. The* originating PCI bus (local or backpanel) is selected by the adrsSpace* parameter. Legal values for this parameter are found in "pci.h". If a* transparent bridge is used to access the Compact PCI bus, the local PCI bus* and the Compact PCI bus share the same address space. In this case, the* local and backpanel address space designators are synonomous.** RETURNS: OK, or ERROR if the address space is unknown or the mapping is not* possible.** SEE ALSO: sysLocalToBusAdrs()*/STATUS sysBusToLocalAdrs ( int adrsSpace, /* bus address space where busAdrs resides */ char * busAdrs, /* bus address to convert */ char ** pLocalAdrs /* where to return local address */ ) { switch (adrsSpace) { case PCI_SPACE_IO_SEC:#ifdef INCLUDE_DEC2155X /* * translate from compact PCI address space to local PCI address * space. */ if ( sysCpciToPciAdrs (PCI_BAR_SPACE_IO, busAdrs, &busAdrs) != OK ) return (ERROR); /* fall through */#endif /* INCLUDE_DEC2155X */ case PCI_SPACE_IO_PRI: /* * translate from local PCI address space to CPU address * space. */ return ( sysPciToCpuAdrs (PCI_BAR_SPACE_IO, busAdrs, pLocalAdrs) ); case PCI_SPACE_MEMIO_SEC: case PCI_SPACE_MEM_SEC:#ifdef INCLUDE_DEC2155X /* * Determine, if possible, the local PCI address which * would be produced if the given cPCI is intercepted by * the drawbridge and passed through to the local PCI bus * (downstream transaction). Note that this call violates * the "pure" model of sysBusToLocalAdrs() which, when * given a cPCI address, produces the local processor * address which would ultimately produce the given cPCI * address in an upstream transaction. The reason for * this is to a support shared memory situation in which * two nodes communicated over a local PCI bus but a third * node in the mix requires over the cPCI bus. In this * case the cPCI bus is the advertised bus (smArg1) and * the nodes which communicate with each other over the * local PCI bus must be able to translate a cPCI bus * address into a local address even though they don't * have upstream windows which access the advertised * shared memory cPCI bus. */ if (sysCpciToPciAdrsDs(PCI_BAR_SPACE_MEM, busAdrs, &busAdrs) != OK) { if ( sysCpciToPciAdrs (PCI_BAR_SPACE_MEM, busAdrs, &busAdrs) != OK) { return (ERROR); } } /* fall through */#endif /* INCLUDE_DEC2155X */ case PCI_SPACE_MEMIO_PRI: case PCI_SPACE_MEM_PRI: /* * translate from local PCI address space to CPU address * space. */ return (sysPciToCpuAdrs (PCI_BAR_SPACE_MEM, busAdrs, pLocalAdrs) ); default: return (ERROR); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -