📄 main.c
字号:
for (i = 0; i < SMtstBlkSz/4; i++) // Write address pattern
{
dWrote = (i | (i << 12) | (i << 24));
if (dWrote == 0xFFFFffff)
dWrote = 0xAA55AA55;
if (dWrote == 0)
dWrote = 0x12345678;
((long *) SMoffset)[i] = dWrote;
}
for (i = 0; i < SMtstBlkSz/4; i++) // Read and check address pattern
{
dWrote = (i | (i << 12) | (i << 24) );
if (dWrote == 0xFFFFffff)
dWrote = 0xAA55AA55;
if (dWrote == 0)
dWrote = 0x12345678;
if ( (dRead = ((long *) SMoffset)[i]) != dWrote )
{
errorHandler (0);
}
}
} // end testSharedMemWithHost_W2
//
// testSharedMemWithHost_R2
//
// 860 only reads just before the end of the first half of Shared Mem.
DWORD testSharedMemWithHost_R2 (void)
{
DWORD SMtstBlkSz;
DWORD SMoffset;
DWORD last, i, dRead, dWrote;
SMtstBlkSz = SHAREDMEMregionsize/2; // in bytes.
SMoffset = CS1_BASE + SHAREDMEMregionoffset ; // Offset from start of 860 access space
last = (0x80/4) - 1;
dWrote = (last | (last << 12) | (last << 24) );
if (dWrote == 0xFFFFffff)
dWrote = 0xAA55AA55;
if (dWrote == 0)
dWrote = 0x12345678;
for (i = 0; i < SMtstBlkSz/4; i++) // Read and check address pattern
{
if ( ((long *) SMoffset)[last] != dWrote )
{
errorHandler (0);
}
}
} // end testSharedMemWithHost_R2
//
// testSharedMemWithHost_3
//
//
// PCI = 0 to 63 R/W
// Local = 64 to 127 R
// PCI = 128 to 16k R/W
//
DWORD testSharedMemWithHost_3 (void)
{
#define SMbase 0x4000
#define SMsize 0x4000
DWORD Localbase1 = SMbase + 0x40;
DWORD Localsize1 = 0x40/4;
DWORD base, i, dRead1, dWrote;
base = CS1_BASE + Localbase1;
for (i = 0 ; i < Localsize1 ; i++)
{
dWrote = 0xBB000000 | i ;
((long *) base)[i] = dWrote;
}
for (i = 0 ; i < Localsize1 ; i++)
{
dWrote = 0xBB000000 | i ;
if ( (dRead1 = ((long *) base)[i]) != dWrote)
{
errorHandler(0);
}
}
} // end testSharedMemWithHost_3
//
// initSharedMem
//
//
void initSharedMem (DWORD pattern)
{
DWORD Localbase = SMbase + 0;
DWORD Localsize = SMsize;
DWORD base, i, dRead;
base = CS1_BASE + Localbase;
for (i = 0 ; i < Localsize/4 ; i++)
{
((long *) base)[i] = pattern;
}
// Check it (not really necessary)
for (i = 0 ; i < Localsize/4 ; i++)
{
if ( (dRead = ((long *) base)[i]) != pattern)
{
errorHandler(0);
}
}
} // end initSharedMem
int boundary = 0x80; // A byte offset.
int blockSize = 0x4; // DWORDs
int guardbandSize = 0; // DWORDs
//
// testSMguardband_PL
//
//
// P over L (PCI-side block is higher in mem than Local side block)
//
DWORD testSMguardband_PL (void)
{
DWORD i, dRead, dWrote;
int base;
base = CS1_BASE + (SMbase + boundary) - (blockSize*4) - (guardbandSize*4) ; // Compute a byte address
// DWORD WRWR...
for (i = 0 ; i < blockSize ; i++)
{
dWrote = 0x11111110 | i ;
((long *) base)[i] = dWrote;
if ( (dRead = ((long *) base)[i]) != dWrote)
{
errorHandler(0);
}
dWrote = 0xEEEEEEE0 | i ;
((long *) base)[i] = dWrote;
if ( (dRead = ((long *) base)[i]) != dWrote)
{
errorHandler(0);
}
}
// DWORD Block (!!!) WRWR...
for (i = 0 ; i < blockSize ; i++)
{
dWrote = 0x11111110 | i ;
((long *) base)[i] = dWrote;
}
for (i = 0 ; i < blockSize ; i++)
{
dWrote = 0x11111110 | i ;
if ( (dRead = ((long *) base)[i]) != dWrote)
{
errorHandler(0);
}
}
// DWORD Block (!!!) WRWR...
for (i = 0 ; i < blockSize ; i++)
{
dWrote = 0xEEEEEEE0 | i ;
((long *) base)[i] = dWrote;
}
for (i = 0 ; i < blockSize ; i++)
{
dWrote = 0xEEEEEEE0 | i ;
if ( (dRead = ((long *) base)[i]) != dWrote)
{
errorHandler(0);
}
}
} // end testSMguardband_PL
void accessTrue_AsTarget (void)
{
DWORD i, j, dRead, dWrote;
DWORD base = CS1_BASE + SMbase; // Compute a byte base address.
// Writes
for (i = 0 ; i < NUMtestBLOCKS ; i++) // Walk the muthaBlock table.
{
enum Side theSide = muthaBlock[i].side;
if (theSide == Local) // diff in local
{
DWORD theSize = muthaBlock[i].size;
DWORD theStart = muthaBlock[i].start;
for (j = theStart/4 ; j < (theStart + theSize)/4 ; j++)
{
dWrote = LOCALduringTEST | (j * 4);
((long *) base)[j] = dWrote;
}
}
} // end Writes
// Reads
for (i = 0 ; i < NUMtestBLOCKS ; i++) // Walk the muthaBlock table.
{
enum Side theSide = muthaBlock[i].side;
if (theSide == Local) // diff in local
{
DWORD theSize = muthaBlock[i].size;
DWORD theStart = muthaBlock[i].start;
// enum ExpectErrs theExpect = muthaBlock[i].expecterrs; // diff in local
for (j = theStart/4 ; j < (theStart + theSize)/4 ; j++)
{
dWrote = LOCALduringTEST | (j * 4);
if ( (dRead = ((long *) base)[j]) != dWrote)
{ // diff in local
errorHandler(0);
}
}
}
} // end Reads
} // end accessTrue_AsTarget
void accessComplement_AsTarget (void)
{
DWORD i, j, dRead, dWrote;
DWORD base = CS1_BASE + SMbase; // Compute a byte base address.
// Writes
for (i = 0 ; i < NUMtestBLOCKS ; i++) // Walk the muthaBlock table.
{
enum Side theSide = muthaBlock[i].side;
if (theSide == Local) // diff in local
{
DWORD theSize = muthaBlock[i].size;
DWORD theStart = muthaBlock[i].start;
for (j = theStart/4 ; j < (theStart + theSize)/4 ; j++)
{
dWrote = ~(LOCALduringTEST | (j * 4));
((long *) base)[j] = dWrote;
}
}
} // end Writes
// Reads
for (i = 0 ; i < NUMtestBLOCKS ; i++) // Walk the muthaBlock table.
{
enum Side theSide = muthaBlock[i].side;
if (theSide == Local) // diff in local
{
DWORD theSize = muthaBlock[i].size;
DWORD theStart = muthaBlock[i].start;
// enum ExpectErrs theExpect = muthaBlock[i].expecterrs; // diff in local
for (j = theStart/4 ; j < (theStart + theSize)/4 ; j++)
{
dWrote = ~(LOCALduringTEST | (j * 4));
if ( (dRead = ((long *) base)[j]) != dWrote)
{ // diff in local
errorHandler(0);
}
}
}
} // end Reads
} // end accessComplement_AsTarget
/*
//
// testI2O
//
//
// Here we test the I2O FIFOs as generic FIFOs, using the FE (FIFO Empty) bit,
// not using the I2O protocol convention that a
// read of all ones (0xFFFFffff) means 'an empty FIFO'. With the generic protocol, data that is
// all ones can actually be sent, whereas with the I2O protocol, all ones is reserved as a signal and
// cannot be a value in the data stream.
//
// Note well: we use the Post (not Free) FIFOs for this first test because the Post FIFOs have
// the FE (FIFO Empty) bit exposed in a register to both host and local. The Free FIFOs do not
// expose this bit.
//
DWORD testI2O ()
{
DWORD hostwrote;
// printf ("Testing I2O...\n");
// Host: Notes about Host Operations start like this line and are not indented.
// 860: Notes about 860 Operations start like this line and are indented.
// I2O Interrupt Enable Masks (set the bit to enable)
#define I2OIMSK_LOFL ( 0x00010000 ) // Local overflow
#define I2OIMSK_POFL ( 0x00020000 ) // PCI overflow
#define I2OIMSK_IBPNE ( 0x00400000 ) // ibp not empty
#define I2OIMSK_OBPNE ( 0x00800000 ) // obp not empty
#define I2OCOMMONMSK 0x8 // Mask used for all I2O interrupt mask and status registers
// Host: Write DWORD x to the Inbound Post FIFO (ibp).
// 860: Because of 'Interrupt Generation' issue with the 3042, we do the following:
i2oregp->limr = 0; // Unmask interrupts in limr.
regp->lint = 0; // Mask all (including I2O) interrupts in lint.
while (1) // Go forever reading from the ibp and writing back to the obp.
{
// 860: Reads x from the IBP.
// 860: Spin waiting for OBP (Outbound Post) not empty. Wait forever.
while ( (i2oregp->lisr & I2OCOMMONMSK) != I2OCOMMONMSK )
;
hostwrote = i2oregp->ibp_ibf; // read from ibp !!!
// 860: Writes x back to the OBP.
i2oregp->obp_obf = hostwrote; // write to obp !!!
// 860: And that's all there is to it on the 860 side !!!
}
// Host: Spin waiting for OBP (Outbound Post) not empty. Timeout if it takes too long.
// Host: Read the Outbound Post FIFO and compare to x above.
// if (errorCnt > 0)
// printf ("\nI2O test failed.\n");
// else
// printf ("\nI2O test passed.\n");
return (errorCnt);
} // end testI2O()
#define I2ODONE 0xFFFFfffe // Reserved value that the host sends the 860 through the I2O FIFOs to terminate a test.
//
// testI2O_2
//
// Test I2O using all ones as the empty signal.
//
DWORD testI2O_2 ()
{
// Note: there is no checking for data integrity on the 860 side (how could we?)
// (is done on the host side), so there is no need for errorCnt, etc. here.
DWORD hostwrote, temp;
// printf ("Testing I2O...\n");
// Host: Notes about Host Operations start like this line.
// 860: Notes about 860 Operations start like this line.
// Host: Write DWORD x to the Inbound Post FIFO (ibp).
/*
writeLED (4, FALSE);
// Do all single DWORD tests first...
while (1) // Go til I2ODONE reading from the ibp and writing back to the obp.
{
// 860: Spin waiting for ibp not empty. Wait forever.
// Caution: we must read exactly as here. We only get one chance to read actual data.
while ( (hostwrote = i2oregp->ibp_ibf) == 0xFFFFffff ) // read from ibp !!!
;
if (hostwrote == I2ODONE) // On I2ODONE, we've read from ibp, but we don't write to obp,
// hence both ibp and obp are empty!!!
break; // Do some other test.
i2oregp->obp_obf = hostwrote; // This is the important line: copy to obp !!!
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -