📄 syslib.c
字号:
* PCI or local is being probed based on the address to be probed.
* If the PCI bus is being probed, the sysPciProbe() routine is called to do the
* special PCI probing. If the local bus is being probed, the routine calls an
* architecture-specific probe routine.
*
* RETURNS: ERROR if the probed address does not respond or causes a MMU fault.
* Returns OK if the probed address responds.
*/
STATUS sysBusProbe
(
char * adrs, /* address to be probed */
int mode, /* VX_READ or VX_WRITE */
int length, /* 1, 2 or 4 byte probe */
char * pVal /* address of value to write OR */
/* address of location to place value read */
)
{
STATUS status;
/* Clear any existing errors/exceptions */
sysProbeErrClr ();
/* Handle PCI bus in special manner */
if (IS_PCI_ADDRESS(adrs))
status = sysPciProbe (adrs, mode, length, pVal);
/* Handle local bus in architecture-specific manner */
else
status = vxMemArchProbe (adrs, mode, length, pVal);
/* Clear any errors/exceptions before exiting */
sysProbeErrClr ();
return (status);
}
/******************************************************************************
*
* sysUsDelay - delay at least the specified amount of time (in microseconds)
*
* This routine will delay for at least the specified amount of time using the
* lower 32 bit "word" of the Time Base register as the timer. The accuracy of
* the delay increases as the requested delay increases due to a certain amount
* of overhead. As an example, a requested delay of 10 microseconds is
* accurate within approximately twenty percent, and a requested delay of 100
* microseconds is accurate within approximately two percent.
*
* NOTE: This routine will not relinquish the CPU; it is meant to perform a
* busy loop delay. The minimum delay that this routine will provide is
* approximately 10 microseconds. The maximum delay is approximately the
* size of UINT32; however, there is no roll-over compensation for the total
* delay time, so it is necessary to back off two times the system tick rate
* from the maximum.
*
* RETURNS: N/A
*/
void sysUsDelay
(
UINT32 delay /* length of time in microsec to delay */
)
{
register UINT baselineTickCount;
register UINT curTickCount;
register UINT terminalTickCount;
register int actualRollover = 0;
register int calcRollover = 0;
UINT ticksToWait;
UINT requestedDelay;
UINT oneUsDelay;
/* Exit if no delay count */
if ((requestedDelay = delay) == 0)
return;
/*
* Get the Time Base Lower register tick count, this will be used
* as the baseline.
*/
baselineTickCount = sysTimeBaseLGet();
/*
* Calculate number of ticks equal to 1 microsecond
*
* The Time Base register and the Decrementer count at the same rate:
* once per 4 System Bus cycles.
*
* e.g., 66666666 cycles 1 tick 1 second 16 tick
* --------------- * ------ * -------- = ----------
* second 4 cycles 1000000 microsec microsec
*/
oneUsDelay = ((DEC_CLOCK_FREQ / 4) / 1000000);
/* Convert delay time into ticks */
ticksToWait = requestedDelay * oneUsDelay;
/* Compute when to stop */
terminalTickCount = baselineTickCount + ticksToWait;
/* Check for expected rollover */
if (terminalTickCount < baselineTickCount)
{
calcRollover = 1;
}
do
{
/*
* Get current Time Base Lower register count.
* The Time Base counts UP from 0 to
* all F's.
*/
curTickCount = sysTimeBaseLGet();
/* Check for actual rollover */
if (curTickCount < baselineTickCount)
{
actualRollover = 1;
}
if (((curTickCount >= terminalTickCount)
&& (actualRollover == calcRollover)) ||
((curTickCount < terminalTickCount)
&& (actualRollover > calcRollover)))
{
/* Delay time met */
break;
}
}
while (TRUE);
}
/******************************************************************************
*
* sysDebugMsg - print a debug string to the console in polled mode.
*
* This routine prints a message to the system console in polled mode and
* optionally exits to the monitor.
*
* RETURNS: N/A
*
*/
void sysDebugMsg
(
char * str,
UINT32 recovery
)
{
int msgSize;
int msgIx;
SIO_CHAN * pSioChan; /* serial I/O channel */
/* add by zoutl delay a while */
for (msgIx = 0; msgIx < 50000; msgIx++)
{
msgSize = msgIx;
}
msgSize = strlen (str);
sysSerialHwInit ();
pSioChan = sysSerialChanGet (0);
sioIoctl (pSioChan, SIO_MODE_SET, (void *) SIO_MODE_POLL);
for (msgIx = 0; msgIx < msgSize; msgIx++)
{
while (sioPollOutput (pSioChan, str[msgIx]) == EAGAIN);
}
/* follow caller's error recovery policy. */
#ifdef DEBUGMSG_RECOVERY
if (recovery == EXIT_TO_SYSTEM_MONITOR)
sysToMonitor (BOOT_NO_AUTOBOOT);
#endif
}
/*****************************************************************************
*
* sysPciInsertLong - Insert field into PCI data long
*
* This function writes a field into a PCI data long without altering any bits
* not present in the field. It does this by first doing a PCI long read
* (into a temporary location) of the PCI data long which contains the field
* to be altered. It then alters the bits in the temporary location to match
* the desired value of the field. It then writes back the temporary location
* with a PCI long write. All PCI accesses are byte and the field to alter is
* specified by the "1" bits in the 'bitMask' parameter.
*
* RETURNS: N/A
*/
void sysPciInsertLong
(
UINT32 adrs, /* PCI address */
UINT32 bitMask, /* Mask which defines field to alter */
UINT32 data /* data written to the offset */
)
{
UINT32 temp;
int key;
key = intLock ();
temp = sysPciInLong (adrs);
temp = (temp & ~bitMask) | (data & bitMask);
sysPciOutLong (adrs, temp);
intUnlock (key);
}
/*****************************************************************************
*
* sysPciInsertWord - Insert field into PCI data word
*
* This function writes a field into a PCI data word without altering any bits
* not present in the field. It does this by first doing a PCI word read
* (into a temporary location) of the PCI data word which contains the field
* to be altered. It then alters the bits in the temporary location to match
* the desired value of the field. It then writes back the temporary location
* with a PCI word write. All PCI accesses are word and the field to alter is
* specified by the "1" bits in the 'bitMask' parameter.
*
* RETURNS: N/A
*/
void sysPciInsertWord
(
UINT32 adrs, /* PCI address */
UINT16 bitMask, /* Mask which defines field to alter */
UINT16 data /* data written to the offset */
)
{
UINT16 temp;
int key;
key = intLock ();
temp = sysPciInWord (adrs);
temp = (temp & ~bitMask) | (data & bitMask);
sysPciOutWord (adrs, temp);
intUnlock (key);
}
/*****************************************************************************
*
* sysPciInsertByte - Insert field into PCI data byte
*
* This function writes a field into a PCI data byte without altering any bits
* not present in the field. It does this by first doing a PCI byte read
* (into a temporary location) of the PCI data byte which contains the field
* to be altered. It then alters the bits in the temporary location to match
* the desired value of the field. It then writes back the temporary location
* with a PCI byte write. All PCI accesses are byte and the field to alter is
* specified by the "1" bits in the 'bitMask' parameter.
*
* RETURNS: N/A
*/
void sysPciInsertByte
(
UINT32 adrs, /* PCI address */
UINT8 bitMask, /* Mask which defines field to alter */
UINT8 data /* data written to the offset */
)
{
UINT8 temp;
int key;
key = intLock ();
temp = sysPciInByte (adrs);
temp = (temp & ~bitMask) | (data & bitMask);
sysPciOutByte (adrs, temp);
intUnlock (key);
}
/*****************************************************************************
*
* sysPciOutByteConfirm - Byte out to PCI memory space and flush buffers.
*
* This function outputs a byte to PCI memory space and then flushes the PCI
* write posting buffers by reading from the target address. Since the PCI
* spec requires the completion of posted writes before the completion of delayed
* reads, when the read completes, the write posting buffers have been flushed.
*
* NOTE: If the write 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. When this occurs, it appears as if a PCI delayed read had
* passed a posted write, which would violate PCI transaction ordering rules.
* If this is a concern, an additional read must be performed outside of this
* routine to guarantee that the confirming read performed in this routine was
* not aliased.
*
* RETURNS: N/A
*/
void sysPciOutByteConfirm
(
UINT32 adrs, /* PCI address */
UINT8 data /* data to be written */
)
{
UINT8 temp;
sysPciOutByte (adrs, data);
temp = sysPciInByte (adrs);
}
/*****************************************************************************
*
* sysPciOutWordConfirm - Word out to PCI memory space and flush buffers.
*
* This function outputs a word to PCI memory space and then flushes the PCI
* write posting buffers by reading from the target address. Since the PCI
* spec requires the completion of posted writes before the completion of delayed
* reads, when the read completes, the write posting buffers have been flushed.
*
* NOTE: If the write 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. When this occurs, it appears as if a PCI delayed read had
* passed a posted write, which would violate PCI transaction ordering rules.
* If this is a concern, an additional read must be performed outside of this
* routine to guarantee that the confirming read performed in this routine was
* not aliased.
*
* RETURNS: N/A
*/
void sysPciOutWordConfirm
(
UINT32 adrs, /* PCI address */
UINT16 data /* data to be written */
)
{
UINT16 temp;
sysPciOutWord (adrs, data);
temp = sysPciInWord (adrs);
}
/*****************************************************************************
*
* sysPciOutLongConfirm - Long word out to PCI memory space and flush buffers.
*
* This function outputs a long word to PCI memory space and then flushes the
* PCI write posting buffers by reading from the target address. Since the PCI
* spec requires the completion of posted writes before the completion of delayed
* reads, when the read completes, the write posting buffers have been flushed.
*
* NOTE: If the write 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. When this occurs, it appears as if a PCI delayed read had
* passed a posted write, which would violate PCI transaction ordering rules.
* If this is a concern, an additional read must be performed outside of this
* routine to guarantee that the confirming read performed in this routine was
* not aliased.
*
* RETURNS: N/A
*/
void sysPciOutLongConfirm
(
UINT32 adrs, /* PCI address */
UINT32 data /* data to be written */
)
{
UINT32 temp;
sysPciOutLong (adrs, data);
temp = sysPciInLong (adrs);
}
/*******************************************************************************
*
* sysIntDisable - disable a bus interrupt level (vector)
*
* This routine disables reception of a specified local or Compact PCI bus
* interrupt. If the interrupt level (vector) specified is used for shared
* memory interrupts, a distributed shared memory interrrupt routine is called
* to disable shared memory interrupts from all PCI or cPCI shared memory
* devices. If the level (vector) is not the one used for shared memory, the
* standard intDisable function is called to disable the interrupt at the MPIC.
*
* RETURNS: The results of sysSmIntDisable or intDisable.
*
* SEE ALSO: sysSmIntDisable, sysIntEnable()
*/
STATUS sysIntDisable
(
int intLevel /* interrupt level (vector) */
)
{
return (intDisable (intLevel));
}
/*******************************************************************************
*
* sysIntEnable - enable a bus interrupt level (vector)
*
* This routine enables reception of a specified local or Compact PCI bus
* interrupt. If the interrupt level (vector)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -