📄 syslib.c
字号:
pRavPci->winBase = temp & ~0xffff; pRavPci->winLimit = (temp << 16) | 0xffff; /* calculate translated values */ pRavCpu->winBase = pRavPci->winBase + (trans << 16); pRavCpu->winLimit = pRavPci->winLimit + (trans << 16); /* advance in preparation for next valid window */ pRavCpu++; pRavPci++; } /* advance to next set of raven offsets */ pRavOff++; } }/******************************************************************************** sysRavenTransAdrs - translate an address that passes through the raven.** 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: sysPci()*/LOCAL STATUS sysRavenTransAdrs ( 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 */ RAVEN_WIN_STRUCT * pSrc, /* pointer to the source windows */ RAVEN_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()*/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 (sysRavenTransAdrs (adrsSpace, (UINT32)localAdrs, (UINT32 *)pBusAdrs, sysValidRavenWindows, &sysRavCpuToPciWin[0], &sysRavPciToCpuWin[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()*/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 (sysRavenTransAdrs (adrsSpace, (UINT32)localAdrs, (UINT32 *)pBusAdrs, sysValidRavenWindows, &sysRavPciToCpuWin[0], &sysRavCpuToPciWin[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); break; } 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) ); break; case PCI_SPACE_MEMIO_SEC: case PCI_SPACE_MEM_SEC:#ifdef INCLUDE_DEC2155X /* * translate from compact PCI address space to local PCI address * space. */ 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) ); break; default: return (ERROR); break; } }/********************************************************************************* sysBusTas - test and set a location across the bus** The cPCI bridge chips do not support PCI target locking, therefore there is* no atomic RMW operation. This routine performs a software-based mutual* exclusion algorithm in place of a true test and set.** NOTE: This algorithm is performed through a PCI-to-PCI bridge to a shared* location that is subject to unprotected access by multiple simultaneous* processors. There is the possibility that the bridge will deliver a delayed* read completion to a PCI bus master which was not the original initiator of* the delayed read. The bridge delivers the delayed read completion to the new* requestor because it believes that the new delayed read request is actually* the original master performing a delayed read retry as required by the PCI* spec. When the original master comes back with the genuine retry, the bridge* treats it as a new request. When this "aliasing" occurs, a read performed* after a write can appear to complete ahead of the write, which is in violation* of PCI transaction ordering rules. Since this algorithm depends on a strict* time-ordered sequence of operations, it can deadlock under this condition.* To prevent the deadlock, a throw-away read must be performed after the initial* write. Since the bridge only remembers once instance of a queued delayed* read request, the throw-away read will "consume" the results of a* mis-directed read completion and subsequent read requests are guaranteed to* be queued and completed after the write.** RETURNS: TRUE if lock acquired.* FALSE if lock not acquired.** SEE ALSO: sysBusTasClear()*/BOOL sysBusTas ( char * adrs /* address to be tested and set */ ) { FAST int value; /* value to place in lock variable */ FAST int nChecks; /* number of times to re-check lock */ FAST int count; /* running count of re-checks */ int oldLvl; /* previous interrupt level */ volatile int * lockAdrs = (int *)adrs; if (sysSmUtilTasValue == 0) sysSmUtilTasValue = (TAS_CONST + sysProcNumGet ())<< 24; value = sysSmUtilTasValue; /* special value to write */ nChecks = DEFAULT_TAS_CHECKS; /* number of checks to do */ /* Lock out interrupts */ oldLvl = intLock (); /* Test that lock variable is initially empty */ if (*lockAdrs != 0) { intUnlock (oldLvl); return (FALSE); /* someone else has lock */ } /* Set lock value */ *lockAdrs = value; /* Perform a preliminary read due to PCI bridge issues */ count = *lockAdrs; /* Check that no one else is trying to take lock */ for (count = 0; count < nChecks; count++) { if (*lockAdrs != value) { intUnlock (oldLvl); return (FALSE); /* someone else stole lock */ } } intUnlock (oldLvl); return (TRUE); /* exclusive access obtained */ }/******************************************************************************** sysBusTasClear - clear a location set by sysBusTas()** This routine clears a bus test and set location. This routine is only* required if the sysBusTas() routine uses special semaphore techniques (such* as bus locking). Since the sysBusTas routine doesn't use any special* semaphore techniques, this routine is a no-op.** If used, the BSP activates this routine by placing its address into the* global variable 'smUtilTasClearRtn'.** RETURNS: N/A** SEE ALSO: sysBusTas()*/void sysBusTasClear ( volatile char * address /* address to be tested-and-cleared */ ) { }#ifdef INCLUDE_ATA/********************************************************************************* sysIntEnablePIC - enable an ISA/PCI interrupt** This function call is used to enable an ISA/PCI interrupt.** RETURNS: OK or ERROR if unable to enable interrupt.*/STATUS sysIntEnablePIC ( int intNum ) { return (intEnable (intNum)); }#endif /* INCLUDE_ATA *//******************************************************************************** sysSpuriousIntHandler - spurious interrupt handler** This is the entry point for spurious interrupts.** NOTE: This routine has no effect.** This routine catches all spurious interrupts. It does nothing at all.** RETURNS: N/A** NOMANUAL*/void sysSpuriousIntHandler (void) { logMsg ("Spurious Interrupt!\n", 0,0,0,0,0,0); }/******************************************************************************** sysNvRead - read one byte from NVRAM** This routine reads a single byte from a specified offset in NVRAM.** RETURNS: The byte from the specified NVRAM offset.*/UCHAR sysNvRead ( ULONG offset /* NVRAM offset to read the byte from */ ) { sysOutByte (NV_RAM_LSB_REG, LSB(offset));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -