Hi Team,
I want to test pcie loopback with external AMC loopback connector. I have taken reference code from pcie sample example it's basically made for two evm to test pci driver. but i have to do with AMC loopback connector. So i just compile that code with pcie_RC_MODE mode and load into the core 0 from CCS. But it was stuck on below logic
/* Below logic indicates that RC wait for EP response */
do {
unsigned int key;
/* Disable Interrupts */
key = _disable_interrupts();
/* Cleanup the prefetch buffer also. */
CSL_XMC_invalidatePrefetchBuffer();
CACHE_invL1d ((void *)dstBuf.buf, PCIE_EXAMPLE_DSTBUF_BYTES, CACHE_FENCE_WAIT);
CACHE_invL2 ((void *)dstBuf.buf, PCIE_EXAMPLE_DSTBUF_BYTES, CACHE_FENCE_WAIT);
/* Reenable Interrupts. */
_restore_interrupts(key);
} while(dstBuf.buf[PCIE_BUFSIZE_APP] != PCIE_EXAMPLE_BUF_FULL);
So where i need to change for loopback with External AMC connector rather EVM. I have attach sample file, go to line number 912
/* ============================================================================
* Copyright (c) Texas Instruments Incorporated 2010
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* @file pcie_sample.c
*
* @brief
* This is the PCIe example code.
*
*/
/**
* In the PCIe sample example two Shannon EVMs are used to test the PCIe driver.
* As described in the following figure, Shannon 1 is configured as a Root Complex
* and Shannon 2 is configured as End Point.
*
* Shannon 1 Shannon 2
* ------------------ -------------------
* | | | |
* | Root | PCIe Link | End Point |
* | Complex | <-------------------------->| |
* | | | |
* ------------------ -------------------
*
* Once the PCIe link is established, the following sequence of actions will happen:
* - Shannon 1 sends data to Shannon 2
* - Shannon 2 waits to receive all the data
* - Shannon 2 sends the data back to Shannon 1
* - Shannon 1 waits to receive all the data
* - Shannon 1 verifies if the received data matches the sent data and declares test pass or fail.
*
*/
#include "pcie_sample.h"
/* Use regular "printf" when not using BIOS */
//#include <xdc/runtime/System.h>
#define System_printf printf
#include <stdio.h>
#include <ti/csl/csl_bootcfgAux.h>
#include <ti/csl/csl_cacheAux.h>
#include <ti/csl/csl_chip.h>
#include <ti/csl/csl_xmcAux.h>
#pragma DATA_SECTION(dstBuf, ".dstBufSec")
/* Cache coherence: Align must be a multiple of cache line size (L2=128 bytes, L1=64 bytes) to operate with cache enabled. */
/* Aligning to 256 bytes because the PCIe inbound offset register masks the last 8bits of the buffer address */
#pragma DATA_ALIGN(dstBuf, 256)
/* last element in the buffer is a marker that indicates the buffer status: full/empty */
#define PCIE_EXAMPLE_MAX_CACHE_LINE_SIZE 128
#define PCIE_EXAMPLE_UINT32_SIZE 4 /* preprocessor #if requires a real constant, not a sizeof() */
#define PCIE_EXAMPLE_DSTBUF_BYTES ((PCIE_BUFSIZE_APP + 1) * PCIE_EXAMPLE_UINT32_SIZE)
#define PCIE_EXAMPLE_DSTBUF_REM (PCIE_EXAMPLE_DSTBUF_BYTES % PCIE_EXAMPLE_MAX_CACHE_LINE_SIZE)
#define PCIE_EXAMPLE_DSTBUF_PAD (PCIE_EXAMPLE_DSTBUF_REM ? (PCIE_EXAMPLE_MAX_CACHE_LINE_SIZE - PCIE_EXAMPLE_DSTBUF_REM) : 0)
struct dstBuf_s {
volatile uint32_t buf[PCIE_BUFSIZE_APP + 1];
/* Cache coherence: Must pad to cache line size in order to enable cacheability */
#if PCIE_EXAMPLE_DSTBUF_PAD
uint8_t padding[PCIE_EXAMPLE_DSTBUF_PAD];
#endif
} dstBuf;
#define PCIE_EXAMPLE_BUF_EMPTY 0
#define PCIE_EXAMPLE_BUF_FULL 1
/* Does not need to be aligned (even for cache) since it is only accessed locally */
uint32_t srcBuf[PCIE_BUFSIZE_APP];
extern volatile unsigned int cregister TSCL;
/* Global config variable that controls
the PCIe mode. It is global so it can be poked
from CCS. It should be set either to EP or RC. */
pcieMode_e PcieModeGbl = pcie_EP_MODE;
/*****************************************************************************
* Function: Power domain configuration
****************************************************************************/
pcieRet_e pciePowerCfg(void)
{
/* Turn on the PCIe power domain */
if (CSL_PSC_getPowerDomainState (CSL_PSC_PD_PCIEX) != PSC_PDSTATE_ON) {
/* Enable the domain */
CSL_PSC_enablePowerDomain (CSL_PSC_PD_PCIEX);
/* Enable MDCTL */
CSL_PSC_setModuleNextState (CSL_PSC_LPSC_PCIEX, PSC_MODSTATE_ENABLE);
/* Apply the domain */
CSL_PSC_startStateTransition (CSL_PSC_PD_PCIEX);
/* Wait for it to finish */
while (! CSL_PSC_isStateTransitionDone (CSL_PSC_PD_PCIEX));
} else {
System_printf ("Power domain is already enabled. You probably re-ran without device reset (which is OK)\n");
}
return pcie_RET_OK;
}
/*****************************************************************************
* Function: Utility function to introduce delay
****************************************************************************/
void cycleDelay (uint32_t count)
{
uint32_t sat;
if (count <= 0)
return;
sat = TSCL + count;
while (TSCL < sat);
}
/*****************************************************************************
* Function: Serdes configuration
****************************************************************************/
pcieRet_e pcieSerdesCfg(void)
{
uint16_t cfg;
CSL_BootCfgUnlockKicker();
/* Provide PLL reference clock to SERDES inside PCIESS
Program PLL settings and enable PLL from PCIe SERDES.*/
cfg = 0x01C9; /* value based on PCIe userguide */
CSL_BootCfgSetPCIEConfigPLL(cfg);
CSL_BootCfgLockKicker();
/*Wait for PLL to lock (3000 CLKIN1 cycles) */
cycleDelay(10000);
return pcie_RET_OK;
}
/*****************************************************************************
* Function: Enable/Disable LTSSM (Link Training)
****************************************************************************/
pcieRet_e pcieLtssmCtrl(Pcie_Handle handle, uint8_t enable)
{
pcieCmdStatusReg_t cmdStatus;
pcieRegisters_t setRegs;
pcieRegisters_t getRegs;
pcieRet_e retVal;
memset (&cmdStatus, 0, sizeof(cmdStatus));
memset (&setRegs, 0, sizeof(setRegs));
memset (&getRegs, 0, sizeof(getRegs));
getRegs.cmdStatus = &cmdStatus;
if ((retVal = Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs)) != pcie_RET_OK)
{
System_printf ("Read CMD STATUS register failed!\n");
return retVal;
}
if(enable)
cmdStatus.ltssmEn = 1;
else
cmdStatus.ltssmEn = 0;
setRegs.cmdStatus = &cmdStatus;
if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK)
{
System_printf ("SET CMD STATUS register failed!\n");
return retVal;
}
return pcie_RET_OK;
}
/*****************************************************************************
* Function: Configure PCIe in Root Complex Mode
****************************************************************************/
pcieRet_e pcieCfgRC(Pcie_Handle handle)
{
pcieRet_e retVal;
pcieCmdStatusReg_t cmdStatus;
pcieObSizeReg_t obSize;
pcieGen2Reg_t gen2;
pcieType1Bar32bitIdx_t type1Bar32bitIdx;
pcieStatusCmdReg_t statusCmd;
pcieDevStatCtrlReg_t devStatCtrl;
pcieAccrReg_t accr;
pcieRegisters_t setRegs;
pcieRegisters_t getRegs;
memset (&cmdStatus, 0, sizeof(cmdStatus));
memset (&obSize, 0, sizeof(obSize));
memset (&gen2, 0, sizeof(gen2));
memset (&type1Bar32bitIdx, 0, sizeof(type1Bar32bitIdx));
memset (&statusCmd, 0, sizeof(statusCmd));
memset (&devStatCtrl, 0, sizeof(devStatCtrl));
memset (&accr, 0, sizeof(accr));
/*Disable link training*/
if ((retVal = pcieLtssmCtrl(handle, FALSE)) != pcie_RET_OK)
{
System_printf ("Failed to disable Link Training!\n");
return retVal;
}
/* Configure the size of the translation regions */
memset (&setRegs, 0, sizeof(setRegs));
memset (&getRegs, 0, sizeof(getRegs));
obSize.size = pcie_OB_SIZE_8MB;
setRegs.obSize = &obSize;
if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK)
{
System_printf ("SET OB_SIZE register failed!\n");
return retVal;
}
/* Setting PL_GEN2 */
memset (&setRegs, 0, sizeof(setRegs));
gen2.numFts = 0xF;
gen2.dirSpd = 0x0;
gen2.lnEn = 1;
setRegs.gen2 = &gen2;
if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK)
{
System_printf ("SET GEN2 register failed!\n");
return retVal;
}
/* Configure BAR Masks */
/* First need to enable writing on BAR mask registers */
memset (&setRegs, 0, sizeof(setRegs));
memset (&getRegs, 0, sizeof(getRegs));
memset (&cmdStatus, 0, sizeof(cmdStatus));
getRegs.cmdStatus = &cmdStatus;
if ((retVal = Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs)) != pcie_RET_OK)
{
System_printf ("Read CMD STATUS register failed!\n");
return retVal;
}
cmdStatus.dbi = 1;
setRegs.cmdStatus = &cmdStatus;
if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK)
{
System_printf ("SET CMD STATUS register failed!\n");
return retVal;
}
/* Configure Masks*/
memset (&setRegs, 0, sizeof(setRegs));
type1Bar32bitIdx.reg.reg32 = PCIE_BAR_MASK;
setRegs.type1Bar32bitIdx = &type1Bar32bitIdx;
/* BAR 0 */
type1Bar32bitIdx.idx = 0; /* configure BAR 0*/
if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK)
{
System_printf ("SET BAR MASK register failed!\n");
return retVal;
}
/* BAR 1 */
type1Bar32bitIdx.idx = 1; /* configure BAR 1*/
if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK)
{
System_printf ("SET BAR MASK register failed!\n");
return retVal;
}
/* Disable writing on BAR Masks */
memset (&setRegs, 0, sizeof(setRegs));
memset (&getRegs, 0, sizeof(getRegs));
memset (&cmdStatus, 0, sizeof(cmdStatus));
getRegs.cmdStatus = &cmdStatus;
if ((retVal = Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs)) != pcie_RET_OK)
{
System_printf ("Read CMD STATUS register failed!\n");
return retVal;
}
cmdStatus.dbi = 0;
setRegs.cmdStatus = &cmdStatus;
if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK)
{
System_printf ("SET CMD STATUS register failed!\n");
return retVal;
}
/* Enable memory access and mastership of the bus */
memset (&setRegs, 0, sizeof(setRegs));
memset (&getRegs, 0, sizeof(getRegs));
getRegs.statusCmd = &statusCmd;
if ((retVal = Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs)) != pcie_RET_OK)
{
System_printf ("Read Status Comand register failed!\n");
return retVal;
}
statusCmd.memSp = 1;
statusCmd.busMs = 1;
statusCmd.resp = 1;
statusCmd.serrEn = 1;
setRegs.statusCmd = &statusCmd;
if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK)
{
System_printf ("SET Status Command register failed!\n");
return retVal;
}
/* Enable Error Reporting */
memset (&setRegs, 0, sizeof(setRegs));
memset (&getRegs, 0, sizeof(getRegs));
getRegs.devStatCtrl = &devStatCtrl;
if ((retVal = Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs)) != pcie_RET_OK)
{
System_printf ("Regad Device Status Control register failed!\n");
return retVal;
}
devStatCtrl.reqRp = 1;
devStatCtrl.fatalErRp = 1;
devStatCtrl.nFatalErRp = 1;
devStatCtrl.corErRp = 1;
setRegs.devStatCtrl = &devStatCtrl;
if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK)
{
System_printf ("SET Device Status Control register failed!\n");
return retVal;
}
/* Enable ECRC */
memset (&setRegs, 0, sizeof(setRegs));
accr.chkEn=1;
accr.chkCap=1;
accr.genEn=1;
accr.genCap=1;
setRegs.accr = &accr;
if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK)
{
System_printf ("SET ACCR register failed!\n");
return retVal;
}
return pcie_RET_OK;
}
/*****************************************************************************
* Function: Configure PCIe in End Point Mode
****************************************************************************/
pcieRet_e pcieCfgEP(Pcie_Handle handle)
{
pcieRet_e retVal;
pcieCmdStatusReg_t cmdStatus;
pcieObSizeReg_t obSize;
pcieGen2Reg_t gen2;
pcieType0Bar32bitIdx_t type0Bar32bitIdx;
pcieStatusCmdReg_t statusCmd;
pcieDevStatCtrlReg_t devStatCtrl;
pcieAccrReg_t accr;
pcieRegisters_t setRegs;
pcieRegisters_t getRegs;
memset (&cmdStatus, 0, sizeof(cmdStatus));
memset (&obSize, 0, sizeof(obSize));
memset (&gen2, 0, sizeof(gen2));
memset (&type0Bar32bitIdx, 0, sizeof(type0Bar32bitIdx));
memset (&statusCmd, 0, sizeof(statusCmd));
memset (&devStatCtrl, 0, sizeof(devStatCtrl));
memset (&accr, 0, sizeof(accr));
/*Disable link training*/
if ((retVal = pcieLtssmCtrl(handle, FALSE)) != pcie_RET_OK)
{
System_printf ("Failed to disable Link Training!\n");
return retVal;
}
/* Configure the size of the translation regions */
memset (&setRegs, 0, sizeof(setRegs));
memset (&getRegs, 0, sizeof(getRegs));
obSize.size = pcie_OB_SIZE_8MB;
setRegs.obSize = &obSize;
if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK)
{
System_printf ("SET OB_SIZE register failed!\n");
return retVal;
}
/* Setting PL_GEN2 */
memset (&setRegs, 0, sizeof(setRegs));
gen2.numFts = 0xF;
gen2.dirSpd = 0x0;
gen2.lnEn = 1;
setRegs.gen2 = &gen2;
if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK)
{
System_printf ("SET GEN2 register failed!\n");
return retVal;
}
/* Configure BAR Masks */
/* First need to enable writing on BAR mask registers */
memset (&setRegs, 0, sizeof(setRegs));
memset (&getRegs, 0, sizeof(getRegs));
memset (&cmdStatus, 0, sizeof(cmdStatus));
getRegs.cmdStatus = &cmdStatus;
if ((retVal = Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs)) != pcie_RET_OK)
{
System_printf ("Read CMD STATUS register failed!\n");
return retVal;
}
cmdStatus.dbi = 1;
setRegs.cmdStatus = &cmdStatus;
if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK)
{
System_printf ("SET CMD STATUS register failed!\n");
return retVal;
}
/* Configure Masks*/
memset (&setRegs, 0, sizeof(setRegs));
type0Bar32bitIdx.reg.reg32 = PCIE_BAR_MASK;
setRegs.type0Bar32bitIdx = &type0Bar32bitIdx;
/* BAR 0 */
type0Bar32bitIdx.idx = 0; /* configure BAR 0*/
if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK)
{
System_printf ("SET BAR MASK register failed!\n");
return retVal;
}
/* BAR 1 */
type0Bar32bitIdx.idx = 1; /* configure BAR 1*/
if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK)
{
System_printf ("SET BAR MASK register failed!\n");
return retVal;
}
/* Disable writing on BAR Masks */
memset (&setRegs, 0, sizeof(setRegs));
memset (&getRegs, 0, sizeof(getRegs));
memset (&cmdStatus, 0, sizeof(cmdStatus));
getRegs.cmdStatus = &cmdStatus;
if ((retVal = Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs)) != pcie_RET_OK)
{
System_printf ("Read CMD STATUS register failed!\n");
return retVal;
}
cmdStatus.dbi = 0;
setRegs.cmdStatus = &cmdStatus;
if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK)
{
System_printf ("SET CMD STATUS register failed!\n");
return retVal;
}
/* Enable memory access and mastership of the bus */
memset (&setRegs, 0, sizeof(setRegs));
memset (&getRegs, 0, sizeof(getRegs));
getRegs.statusCmd = &statusCmd;
if ((retVal = Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs)) != pcie_RET_OK)
{
System_printf ("Read Status Comand register failed!\n");
return retVal;
}
statusCmd.memSp = 1;
statusCmd.busMs = 1;
statusCmd.resp = 1;
statusCmd.serrEn = 1;
setRegs.statusCmd = &statusCmd;
if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK)
{
System_printf ("SET Status Command register failed!\n");
return retVal;
}
/* Enable Error Reporting */
memset (&setRegs, 0, sizeof(setRegs));
memset (&getRegs, 0, sizeof(getRegs));
getRegs.devStatCtrl = &devStatCtrl;
if ((retVal = Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs)) != pcie_RET_OK)
{
System_printf ("Regad Device Status Control register failed!\n");
return retVal;
}
devStatCtrl.reqRp = 1;
devStatCtrl.fatalErRp = 1;
devStatCtrl.nFatalErRp = 1;
devStatCtrl.corErRp = 1;
setRegs.devStatCtrl = &devStatCtrl;
if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK)
{
System_printf ("SET Device Status Control register failed!\n");
return retVal;
}
/* Enable ECRC */
memset (&setRegs, 0, sizeof(setRegs));
accr.chkEn=1;
accr.chkCap=1;
accr.genEn=1;
accr.genCap=1;
setRegs.accr = &accr;
if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK)
{
System_printf ("SET ACCR register failed!\n");
return retVal;
}
return pcie_RET_OK;
}
/*****************************************************************************
* Function: Configure and enable Outbound Address Translation
****************************************************************************/
pcieRet_e pcieObTransCfg(Pcie_Handle handle, uint32_t obAddrLo, uint32_t obAddrHi, uint8_t region)
{
pcieRet_e retVal;
pcieRegisters_t setRegs;
pcieRegisters_t getRegs;
pcieCmdStatusReg_t cmdStatus;
memset (&setRegs, 0, sizeof(setRegs));
memset (&getRegs, 0, sizeof(getRegs));
memset (&cmdStatus, 0, sizeof(cmdStatus));
/* Set outbound offset registers */
if ((retVal = Pcie_cfgObOffset(handle, obAddrLo, obAddrHi, region)) != pcie_RET_OK)
{
System_printf ("Failed to configure ObOffset registers!\n");
return retVal;
}
/*enable Outbound address translation*/
memset (&setRegs, 0, sizeof(setRegs));
memset (&getRegs, 0, sizeof(getRegs));
getRegs.cmdStatus = &cmdStatus;
if ((retVal = Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs)) != pcie_RET_OK)
{
System_printf ("Read CMD STATUS register failed!\n");
return retVal;
}
cmdStatus.obXltEn = 1;
setRegs.cmdStatus = &cmdStatus;
if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK)
{
System_printf ("SET CMD STATUS register failed!\n");
return retVal;
}
return pcie_RET_OK;
}
/*****************************************************************************
* Function: Configure and enable Inbound Address Translation
****************************************************************************/
pcieRet_e pcieIbTransCfg(Pcie_Handle handle, pcieIbTransCfg_t *ibCfg)
{
pcieRet_e retVal;
pcieRegisters_t setRegs;
pcieRegisters_t getRegs;
pcieCmdStatusReg_t cmdStatus;
memset (&setRegs, 0, sizeof(setRegs));
memset (&getRegs, 0, sizeof(getRegs));
memset (&cmdStatus, 0, sizeof(cmdStatus));
/* Set outbound offset registers */
if ((retVal = Pcie_cfgIbTrans(handle, ibCfg)) != pcie_RET_OK)
{
System_printf ("Failed to configure Inbound Translation registers!\n");
return retVal;
}
/*enable Inbound address translation*/
memset (&setRegs, 0, sizeof(setRegs));
memset (&getRegs, 0, sizeof(getRegs));
getRegs.cmdStatus = &cmdStatus;
if ((retVal = Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs)) != pcie_RET_OK)
{
System_printf ("Read CMD STATUS register failed!\n");
return retVal;
}
cmdStatus.ibXltEn = 1;
setRegs.cmdStatus = &cmdStatus;
if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK)
{
System_printf ("SET CMD STATUS register failed!\n");
return retVal;
}
return pcie_RET_OK;
}
/*****************************************************************************
* Function: Initialize application buffers
****************************************************************************/
void pcieInitAppBuf(void)
{
uint32_t i;
for (i=0; i<PCIE_BUFSIZE_APP; i++)
{
dstBuf.buf[i] = 0;
srcBuf[i] = i;
}
dstBuf.buf[PCIE_BUFSIZE_APP] = PCIE_EXAMPLE_BUF_EMPTY;
}
/*****************************************************************************
* Function: Check LTSSM status and wait for the link to be up
****************************************************************************/
void pcieWaitLinkUp(Pcie_Handle handle)
{
pcieRegisters_t getRegs;
pcieDebug0Reg_t debug0;
memset (&debug0, 0, sizeof(debug0));
memset (&getRegs, 0, sizeof(getRegs));
uint8_t ltssmState = 0;
while(ltssmState != pcie_LTSSM_L0)
{
cycleDelay(100);
getRegs.debug0 = &debug0;
if (Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs) != pcie_RET_OK)
{
System_printf ("Read LTSSM state failed!\n");
return;
}
ltssmState = debug0.ltssmState;
}
}
/*****************************************************************************
* Function: Converts a core local L2 address to a global L2 address
* Input addr: L2 address to be converted to global.
* return: uint32_t Global L2 address
*****************************************************************************/
uint32_t pcieConvert_CoreLocal2GlobalAddr (uint32_t addr)
{
uint32_t coreNum;
/* Get the core number. */
coreNum = CSL_chipReadReg(CSL_CHIP_DNUM);
/* Compute the global address. */
return ((1 << 28) | (coreNum << 24) | (addr & 0x00ffffff));
}
/*****************************************************************************
* Function: Main
****************************************************************************/
void main (void)
{
TSCL = 1;
uint16_t lock=0;
pcieRet_e retVal;
pcieIbTransCfg_t ibCfg;
pcieBarCfg_t barCfg;
Pcie_Handle handle = NULL;
void *pcieBase;
uint32_t i;
System_printf ("**********************************************\n");
System_printf ("* PCIe Test Start *\n");
if(PcieModeGbl == pcie_RC_MODE)
System_printf ("* RC mode *\n");
else
System_printf ("* EP mode *\n");
System_printf ("**********************************************\n\n");
System_printf ("Version #: 0x%08x; string %s\n\n", Pcie_getVersion(), Pcie_getVersionStr());
/* Initialize application buffers */
pcieInitAppBuf();
/* Configure SERDES*/
if ((retVal = pcieSerdesCfg()) != pcie_RET_OK) {
System_printf ("PCIe Serdes config failed (%d)\n", (int)retVal);
exit(1);
}
/* Set the PCIe mode*/
if ((retVal = Pcie_setMode(PcieModeGbl)) != pcie_RET_OK) {
System_printf ("Set PCIe Mode failed (%d)\n", (int)retVal);
exit(1);
}
/* Power up PCIe Module */
if ((retVal = pciePowerCfg()) != pcie_RET_OK) {
System_printf ("PCIe Power Up failed (%d)\n", (int)retVal);
exit(1);
}
System_printf ("PCIe Power Up.\n");
/* Wait until the PCIe SERDES PLL locks */
while (!lock)
{
CSL_BootCfgGetPCIEPLLLock(&lock);
}
if ((retVal = Pcie_open(0, &handle)) != pcie_RET_OK)
{
System_printf ("Open failed (%d)\n", (int)retVal);
exit(1);
}
System_printf ("PLL configured.\n");
if(PcieModeGbl == pcie_RC_MODE)
{
/* Configure application registers for Root Complex*/
if ((retVal = pcieCfgRC(handle)) != pcie_RET_OK)
{
System_printf ("Failed to configure PCIe in RC mode (%d)\n", (int)retVal);
exit(1);
}
/* Configure Address Translation */
barCfg.location = pcie_LOCATION_LOCAL;
barCfg.mode = pcie_RC_MODE;
barCfg.base = PCIE_IB_LO_ADDR_M;
barCfg.prefetch = pcie_BAR_NON_PREF;
barCfg.type = pcie_BAR_TYPE32;
barCfg.memSpace = pcie_BAR_MEM_MEM;
barCfg.idx = PCIE_BAR_IDX_M;
if ((retVal = Pcie_cfgBar(handle, &barCfg)) != pcie_RET_OK)
{
System_printf ("Failed to configure BAR (%d)\n", (int)retVal);
exit(1);
}
ibCfg.ibBar = PCIE_BAR_IDX_M; /* Match BAR that was configured above*/
ibCfg.ibStartAddrLo = PCIE_IB_LO_ADDR_M;
ibCfg.ibStartAddrHi = PCIE_IB_HI_ADDR_M;
ibCfg.ibOffsetAddr = (uint32_t)pcieConvert_CoreLocal2GlobalAddr ((uint32_t)dstBuf.buf);
ibCfg.region = PCIE_IB_REGION_M;
if ((retVal = pcieIbTransCfg(handle, &ibCfg)) != pcie_RET_OK)
{
System_printf ("Failed to configure Inbound Translation (%d)\n", (int)retVal);
exit(1);
}
else
{
System_printf ("Successfully configured Inbound Translation!\n");
}
if ((retVal = pcieObTransCfg (handle, PCIE_OB_LO_ADDR_M, PCIE_OB_HI_ADDR_M, PCIE_OB_REGION_M)) != pcie_RET_OK)
{
System_printf ("Failed to configure Outbound Address Translation (%d)\n", (int)retVal);
exit(1);
}
else
{
System_printf ("Successfully configured Outbound Translation!\n");
}
}
else
{
/* Configure application registers for End Point*/
if ((retVal = pcieCfgEP(handle)) != pcie_RET_OK)
{
System_printf ("Failed to configure PCIe in EP mode (%d)\n", (int)retVal);
exit(1);
}
/* Configure Address Translation */
barCfg.location = pcie_LOCATION_LOCAL;
barCfg.mode = pcie_EP_MODE;
barCfg.base = PCIE_IB_LO_ADDR_S;
barCfg.prefetch = pcie_BAR_NON_PREF;
barCfg.type = pcie_BAR_TYPE32;
barCfg.memSpace = pcie_BAR_MEM_MEM;
barCfg.idx = PCIE_BAR_IDX_S;
if ((retVal = Pcie_cfgBar(handle, &barCfg)) != pcie_RET_OK)
{
System_printf ("Failed to configure BAR!\n");
exit(1);
}
ibCfg.ibBar = PCIE_BAR_IDX_S; /* Match BAR that was configured above*/
ibCfg.ibStartAddrLo = PCIE_IB_LO_ADDR_S;
ibCfg.ibStartAddrHi = PCIE_IB_HI_ADDR_S;
ibCfg.ibOffsetAddr = (uint32_t)pcieConvert_CoreLocal2GlobalAddr ((uint32_t)dstBuf.buf);
ibCfg.region = PCIE_IB_REGION_S;
if ((retVal = pcieIbTransCfg(handle, &ibCfg)) != pcie_RET_OK)
{
System_printf ("Failed to configure Inbound Translation!\n", (int)retVal);
exit(1);
}
else
{
System_printf ("Successfully configured Inbound Translation!\n");
}
if ((retVal = pcieObTransCfg (handle, PCIE_OB_LO_ADDR_S, PCIE_OB_HI_ADDR_S, PCIE_OB_REGION_S)) != pcie_RET_OK)
{
System_printf ("Failed to configure Outbound Address Translation!\n", (int)retVal);
exit(1);
}
else
{
System_printf ("Successfully configured Outbound Translation!\n");
}
}
System_printf ("Starting link training...\n");
/*Enable link training*/
if ((retVal = pcieLtssmCtrl(handle, TRUE)) != pcie_RET_OK)
{
System_printf ("Failed to Enable Link Training!\n", (int)retVal);
exit(1);
}
/* Wait for link to be up */
pcieWaitLinkUp(handle);
System_printf ("Link is up.\n");
if(PcieModeGbl == pcie_RC_MODE)
{
/**********************************************************************/
/* Push a single message to the EP then verify that it is echoed back */
/**********************************************************************/
/* Write from RC to EP */
if ((retVal = Pcie_getMemSpaceRange (handle, &pcieBase, NULL)) != pcie_RET_OK) {
System_printf ("getMemSpaceRange failed\n", (int)retVal);
exit(1);
}
for (i=0; i<PCIE_BUFSIZE_APP; i++)
{
*((volatile uint32_t *)pcieBase + i) = srcBuf[i];
}
/* Mark that the buffer is full, so EP can process it */
*((volatile uint32_t *)pcieBase + PCIE_BUFSIZE_APP) = PCIE_EXAMPLE_BUF_FULL;
/* Note on cache coherence: Write back is not necessary because pcieBase is in
peripheral address space instead of physical memory*/
/* Data sent to EP.
RC waits for the loopback to be completed and
receive data back from EP */
do {
unsigned int key;
/* Disable Interrupts */
key = _disable_interrupts();
/* Cleanup the prefetch buffer also. */
CSL_XMC_invalidatePrefetchBuffer();
CACHE_invL1d ((void *)dstBuf.buf, PCIE_EXAMPLE_DSTBUF_BYTES, CACHE_FENCE_WAIT);
CACHE_invL2 ((void *)dstBuf.buf, PCIE_EXAMPLE_DSTBUF_BYTES, CACHE_FENCE_WAIT);
/* Reenable Interrupts. */
_restore_interrupts(key);
} while(dstBuf.buf[PCIE_BUFSIZE_APP] != PCIE_EXAMPLE_BUF_FULL);
/* check all the data */
for (i=0; i<PCIE_BUFSIZE_APP; i++)
{
if(dstBuf.buf[i] != srcBuf[i])
{
System_printf ("Received data = %d\nTransmited data = %d\nIndex = %d.\n\nTest failed.\n",
dstBuf.buf[i], srcBuf[i], i);
exit(1);
}
}
System_printf ("Root Complex received data.\nTest passed.\n");
}
else
{
/**********************************************************************/
/* Wait for a single message from the RC then echo it back */
/**********************************************************************/
/* EP waits for the data received from RC */
do {
unsigned int key;
/* Disable Interrupts */
key = _disable_interrupts();
/* Cleanup the prefetch buffer also. */
CSL_XMC_invalidatePrefetchBuffer();
CACHE_invL1d ((void *)dstBuf.buf, PCIE_EXAMPLE_DSTBUF_BYTES, CACHE_FENCE_WAIT);
CACHE_invL2 ((void *)dstBuf.buf, PCIE_EXAMPLE_DSTBUF_BYTES, CACHE_FENCE_WAIT);
/* Reenable Interrupts. */
_restore_interrupts(key);
} while(dstBuf.buf[PCIE_BUFSIZE_APP] != PCIE_EXAMPLE_BUF_FULL);
System_printf ("End Point received data.\n");
/* Loopback to RC what was written in the DST buffer.
Write from EP to RC */
if ((retVal = Pcie_getMemSpaceRange (handle, &pcieBase, NULL)) != pcie_RET_OK) {
System_printf ("getMemSpaceRange failed\n", (int)retVal);
exit(1);
}
for (i=0; i<PCIE_BUFSIZE_APP; i++)
{
*((volatile uint32_t *)pcieBase + i) = dstBuf.buf[i];
}
/* Mark that the buffer is full, so RC can process it */
*((volatile uint32_t *)pcieBase + PCIE_BUFSIZE_APP) = PCIE_EXAMPLE_BUF_FULL;
/* Note on cache coherence: Write back is not necessary because pcieBase is in
peripheral address space instead of physical memory*/
System_printf ("End Point sent data to Root Complex, completing the loopback.\nEnd of Test.\n");
}
exit(0);
}