📄 pspanlib.c
字号:
PB_SI6_RD_AMT );
PspanPbSlaveImageSetup( pspan,
7, PB_SI7_BASE_ADDR,
PB_SI7_XLAT_ADDR,
PB_SI7_BLOCK_SIZE,
PB_SI7_RD_AMT );
PspanPbSlaveImageMiscSetup( pspan, 0,
LITTLE_ENDIAN,
PCI1, FALSE );
PspanPbSlaveImageMiscSetup( pspan, 1,
LITTLE_ENDIAN,
PCI1, FALSE );
PspanPbSlaveImageMiscSetup( pspan, 2,
LITTLE_ENDIAN,
PCI1, FALSE );
PspanPbSlaveImageMiscSetup( pspan, 3,
LITTLE_ENDIAN,
PCI1, FALSE );
PspanPbSlaveImageMiscSetup( pspan, 4,
LITTLE_ENDIAN,
PCI2, FALSE );
PspanPbSlaveImageMiscSetup( pspan, 5,
LITTLE_ENDIAN,
PCI1, FALSE );
PspanPbSlaveImageMiscSetup( pspan, 6,
LITTLE_ENDIAN,
PCI1, FALSE );
PspanPbSlaveImageMiscSetup( pspan, 7,
LITTLE_ENDIAN,
PCI1, FALSE );
#endif MONITOR_TEST
return ( retval );
} /* PspanImagesSetup */
/*=========================================================================
* Function Name: PspanExtendedCycles
*
* Arguments:
* enable_disable TRUE=enable FALSE=disable
* pspan pointer to PowerSpan register space structure
*
* Description:
* Enable/Disable PowerSpan extended cycles capabilities.
*
* Return Value: SUCCESS/FAILURE
*
=========================================================================*/
void PspanExtendedCycles
(
PPSPAN pspan,
UINT32 enable_disable
)
{
UINT32 temp;
if ( TRUE == enable_disable )
{
/* Enable PowerSpan Extended Cycles */
temp = pspan->pb_misc_csr;
temp |= PB_MISC_CSR_EXTCYC;
pspan->pb_misc_csr = temp;
}
else
{
/* Disable PowerSpan Extended Cycles */
temp = pspan->pb_misc_csr;
temp &= ~(PB_MISC_CSR_EXTCYC);
pspan->pb_misc_csr = temp;
}
return;
} /* PowerSpan_Enable_Extended_Cycles */
/*=========================================================================
* Function Name: PspanInterruptsSetup
*
* Arguments:
* pspan pointer to PowerSpan register space structure
*
* Description:
* Setup PowerSpan interrupts.
*
* Return Value: SUCCESS/FAILURE
*
=========================================================================*/
UINT32 PspanInterruptsSetup
(
PPSPAN pspan
)
{
UINT32 retval = SUCCESS;
/*
* For Coppermine, setup INT_[0] as output.
* PowerSpan's INT_[0] is connected to 8260's IRQ6_.
*
*/
pspan->idr |= IDR_INT0_HW_DIR;
/* map all mailboxes to INT_[0] */
pspan->imr_mbox = IMR_MAP_INT0_VAL &
( IMR_MBOX_MBOX7_MAP |
IMR_MBOX_MBOX6_MAP |
IMR_MBOX_MBOX5_MAP |
IMR_MBOX_MBOX4_MAP |
IMR_MBOX_MBOX3_MAP |
IMR_MBOX_MBOX2_MAP |
IMR_MBOX_MBOX1_MAP |
IMR_MBOX_MBOX0_MAP );
/* map all doorbells to INT_[0] */
pspan->imr_db = IMR_MAP_INT0_VAL &
( IMR_DB_DB7_MAP |
IMR_DB_DB6_MAP |
IMR_DB_DB5_MAP |
IMR_DB_DB4_MAP |
IMR_DB_DB3_MAP |
IMR_DB_DB2_MAP |
IMR_DB_DB1_MAP |
IMR_DB_DB0_MAP );
/* map all DMA interrupts to INT_[0] */
pspan->imr_dma = IMR_MAP_INT0_VAL &
( IMR_DMA_DMA3_MAP |
IMR_DMA_DMA2_MAP |
IMR_DMA_DMA1_MAP |
IMR_DMA_DMA0_MAP );
/* map all h/w interrupts to INT_[0] */
pspan->imr_hw = IMR_MAP_INT0_VAL &
( IMR_HW_P2_HW_MAP |
IMR_HW_P1_HW_MAP |
IMR_HW_INT5_HW_MAP |
IMR_HW_INT4_HW_MAP |
IMR_HW_INT3_HW_MAP |
IMR_HW_INT2_HW_MAP |
IMR_HW_INT1_HW_MAP |
IMR_HW_INT0_HW_MAP );
/* map all P1 interrupts to INT_[0] */
pspan->imr_p1 = IMR_MAP_INT0_VAL &
( IMR_P1_P1_P2_ERR_MAP |
IMR_P1_P1_PB_ERR_MAP |
IMR_P1_P1_P1_ERR_MAP |
IMR_P1_P1_A_PAR_MAP |
IMR_P1_P1_P2_RETRY_MAP |
IMR_P1_P1_PB_RETRY_MAP |
IMR_P1_P1_P1_RETRY_MAP );
/* map all P2 interrupts to INT_[0] */
pspan->imr_p2 = IMR_MAP_INT0_VAL &
( IMR_P2_P2_P1_ERR_MAP |
IMR_P2_P2_PB_ERR_MAP |
IMR_P2_P2_P2_ERR_MAP |
IMR_P2_P2_A_PAR_MAP |
IMR_P2_P2_P1_RETRY_MAP |
IMR_P2_P2_PB_RETRY_MAP |
IMR_P2_P2_P2_RETRY_MAP );
/* map all PB interrupts to INT_[0] */
pspan->imr_pb = IMR_MAP_INT0_VAL &
( IMR_PB_PB_P1_ERR_MAP |
IMR_PB_PB_P2_ERR_MAP |
IMR_PB_PB_PB_ERR_MAP |
IMR_PB_PB_A_PAR_MAP |
IMR2_PB_PB_P1_RETRY_MAP |
IMR2_PB_PB_P2_RETRY_MAP |
IMR2_PB_PB_PB_RETRY_MAP );
pspan->imr2_pb = IMR_MAP_INT0_VAL &
( IMR2_PB_PB_P1_RETRY_MAP |
IMR2_PB_PB_P2_RETRY_MAP |
IMR2_PB_PB_PB_RETRY_MAP );
/* map all misc interrupts to INT_[0] */
pspan->imr_misc = IMR_MAP_INT0_VAL &
( IMR_MISC_I2O_IOP_MAP |
IMR_MISC_I2O_HOST_MAP );
/* enable mailbox 0-3 and error interrupts */
pspan->ier0 =
IR0_MBOX3 |
IR0_MBOX2 |
IR0_MBOX1 |
IR0_MBOX0;
/* program MAX_RETRY */
pspan->p1.misc_csr |= PCI_MISC_CSR_MAX_RETRY;
pspan->p2.misc_csr |= PCI_MISC_CSR_MAX_RETRY;
pspan->pb_misc_csr |= PB_MISC_CSR_MAX_RETRY;
/* enable all error interrupts */
pspan->ier1 = 0xffffffff;
return( retval );
} /* PspanInterruptsSetup */
/*=========================================================================
* Function Name: PspanSimpleDirectModeDma
*
* Arguments:
* pspan pointer to PowerSpan register space structure
* src_addr source address
* dst_addr destination address
* src_port source port (PB/PCI1/PCI2)
* dst_port destination port (PB/PCI1/PCI2)
* byte_count byte count (>0)
*
* Description:
* Perform a direct mode DMA transfer and polls the DMAx_GCSR[DACT] bit
* until done. DMA is performed with channel 0.
*
* Return Value: SUCCESS/FAILURE
*
=========================================================================*/
UINT32 PspanSimpleDirectModeDma
(
PPSPAN pspan,
UINT32 src_addr,
UINT32 dst_addr,
UINT32 src_port,
UINT32 dst_port,
UINT32 byte_count
)
{
UINT32 retval;
UINT32 read_val;
UINT32 temp;
retval = SUCCESS;
/* make sure DMA channel 0 is not active */
read_val = pspan->dma[0].gcsr;
temp = read_val & DMA_GCSR_DACT;
if ( temp != 0 )
{
retval = FAILURE;
}
else
{
/* DMA is not active */
/* source and destination addresses */
pspan->dma[0].src_addr = src_addr;
pspan->dma[0].dst_addr = dst_addr;
/* program source/dest ports and byte count, little endian - no swap */
temp = 0;
if ( src_port == PCI1 )
temp = temp | DMAx_TCR_SRC_PORT_P1_VAL;
else if ( src_port == PCI2 )
temp = temp | DMAx_TCR_SRC_PORT_P2_VAL;
else if ( src_port == PB )
temp = temp | DMAx_TCR_SRC_PORT_PB_VAL;
if ( dst_port == PCI1 )
temp = temp | DMAx_TCR_DST_PORT_P1_VAL;
else if ( dst_port == PCI2 )
temp = temp | DMAx_TCR_DST_PORT_P2_VAL;
else if ( dst_port == PB )
temp = temp | DMAx_TCR_DST_PORT_PB_VAL;
temp = temp | ( DMA_TCR_BC & byte_count );
pspan->dma[0].tcr = temp;
/* zero out DMAx_CPP */
pspan->dma[0].cpp = 0;
DBG1( "DMA0_SRC_ADDR : %08x\r\n",
pspan->dma[0].src_addr );
DBG1( "DMA0_DST_ADDR : %08x\r\n",
pspan->dma[0].dst_addr );
DBG1( "DMA0_TCR : %08x\r\n",
pspan->dma[0].tcr );
/* DMAx_ATTR */
pspan->dma[0].attr |= DMA_ATTR_CI_;
/* set GO bit and clear all status bits at the same time */
temp = 0;
temp = DMA_GCSR_GO |
DMA_GCSR_P1_ERR |
DMA_GCSR_P2_ERR |
DMA_GCSR_PB_ERR |
DMA_GCSR_STOP |
DMA_GCSR_HALT |
DMA_GCSR_DONE;
pspan->dma[0].gcsr = temp;
/* Wait until a DMA status bit is set */
while ( ( (read_val = pspan->dma[0].gcsr) & 0x3f00 ) == 0 );
if ( (read_val & DMA_GCSR_P1_ERR ) == 0 &&
(read_val & DMA_GCSR_P2_ERR ) == 0 &&
(read_val & DMA_GCSR_PB_ERR ) == 0 &&
(read_val & DMA_GCSR_DONE ) == DMA_GCSR_DONE )
{
DBG0( "\r\nDMA ended sucessfully!!\r\n" );
DBG1( "DMA0_GCSR : %08x\r\n", pspan->dma[0].gcsr );
retval = SUCCESS;
}
else
{
DBG0( "\r\nDMA ended unsucessfully ...\r\n" );
DBG1( "DMA0_GCSR : %08x\r\n", pspan->dma[0].gcsr );
retval = FAILURE; /* DMA ended with errors */
}
}
return ( retval );
} /* PspanSimpleDirectModeDma */
/*=========================================================================
* Function Name: PspanCreateCommandPacket
*
* Arguments:
* p_PowerSpanCmdPktDef pointer to a command packet structure
* src_addr source address
* dst_addr destination address
* src_port source port (PB/PCI1/PCI2)
* dst_port destination port (PB/PCI1/PCI2)
* byte_count byte count (>0)
* next_cmd_pkt_ptr 32 byte aligned address to next command packet
* last last command packet (TRUE/FALSE)
*
* Description:
* Generates a command packet at the address p_PowerSpanCmdPktDef.
*
* Return Value: SUCCESS/FAILURE
*
=========================================================================*/
UINT32 PspanCreateCommandPacket
(
struct PowerSpanCmdPktDef
*p_PowerSpanCmdPktDef,
UINT32 src_addr,
UINT32 dst_addr,
UINT32 src_port,
UINT32 dst_port,
UINT32 byte_count,
struct PowerSpanCmdPktDef* next_cmd_pkt_ptr,
UINT32 last
)
{
UINT32 retval = SUCCESS;
UINT32 temp;
/* source and dest addresses */
p_PowerSpanCmdPktDef->DMAx_SRC_ADDR = src_addr;
p_PowerSpanCmdPktDef->DMAx_DST_ADDR = dst_addr;
/* src/dest ports and byte count - little endian */
temp = 0;
if ( src_port == PCI1 )
temp = temp | DMAx_TCR_SRC_PORT_P1_VAL;
else if ( src_port == PCI2 )
temp = temp | DMAx_TCR_SRC_PORT_P2_VAL;
else if ( src_port == PB )
temp = temp | DMAx_TCR_SRC_PORT_PB_VAL;
if ( dst_port == PCI1 )
temp = temp | DMAx_TCR_DST_PORT_P1_VAL;
else if ( dst_port == PCI2 )
temp = temp | DMAx_TCR_DST_PORT_P2_VAL;
else if ( dst_port == PB )
temp = temp | DMAx_TCR_DST_PORT_PB_VAL;
temp = temp | ( DMA_TCR_BC & byte_count );
p_PowerSpanCmdPktDef->DMAx_TCR = temp;
temp = 0;
/* pointer to next cmd packet */
temp = (UINT32) next_cmd_pkt_ptr & DMA_CPP_NCP;
if ( last == TRUE )
temp = temp | DMA_CPP_LAST;
p_PowerSpanCmdPktDef->DMAx_CPP = temp;
return ( retval );
} /* PspanCreateCommandPacket */
/*=========================================================================
* Function Name: PspanSimpleLinkedListModeDma
*
* Arguments:
* pspan pointer to PowerSpan register space structure
* src_addr source address
* dst_addr destination address
* src_port source port (PB/PCI1/PCI2)
* dst_port destination port (PB/PCI1/PCI2)
* byte_count byte count (>0)
*
* Description:
* Simple link list mode DMA that polls the DMAx_GCSR[DACT] bit until
* done. DMA is performed with channel 0.
*
* Return Value: SUCCESS/FAILURE
*
* Notes:
* - Command packet should be 32 byte aligned - to be done
*
=========================================================================*/
UINT32 PspanSimpleLinkedListModeDma
(
PPSPAN pspan,
UINT32 src_addr,
UINT32 dst_addr,
UINT32 src_port,
UINT32 dst_port,
UINT32 byte_count
)
{
UINT32 retval;
UINT32 read_val;
UINT32 temp;
struct PowerSpanCmdPktDef cmd_pkt; /* command packet on PB side */
retval = SUCCESS;
/* create command packet - only 1 packet */
PspanCreateCommandPacket( &cmd_pkt, src_addr, dst_addr,
src_port, dst_port, byte_count, 0, TRUE );
/* ensure DMA0_TCR[BC]=0 */
pspan->dma[0].tcr = 0;
/* set address of command packet */
pspan->dma[0].cpp = (UINT32) &cmd_pkt;
/* set CPA_PORT in DMAx_ATTR to PB */
temp = pspan->dma[0].attr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -