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); }