Hello,
I am trying to get the \mcsdk\pdk_C6678_1_0_0_17\packages\ti\drv\exampleProjects\SRIO_MulticoreLoopbackexampleProject to work. It seems odd but my cache/shared variables seems to not be updating. Any suggestions as to what might cause this?
It was using the ti/csl/csl_cacheAux.h functions. I changed it to use the ti/sysbios/family/c66/Cache.h functions becuase these were working in my SRIOchipTochip example. However, neither set of functions allow the isSRIOInitialized variable to be updated for the non-initializing cores to see. While core1 is able to just move forward core 0, 2 and 3 are stuck waiting for isSRIOInitialized to equal 1.
Attached is the .c file for you reference. Please advise.
Thanks,
Brandy
/**
* @file multicoreLoopback.c
*
* @brief
* This is an example application which showcases how the SRIO Driver
* API can be used in a multiple core environment.
*
* The test suite sends/receives data as follows:-
*
* CORE 1 --> CORE 2 --> CORE 3 --> CORE 0 --> CORE 1
*
* At each step the received data is validated (Payload and Received
* Identifiers).
*
* The goal of the test suite is to showcase that the SRIO Driver API
* are multi-core safe.
*
* \par
* NOTE:
* (C) Copyright 2009 Texas Instruments, Inc.
*
* 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.
*
* \par
*/
#include <xdc/std.h>
#include <string.h>
#include <xdc/runtime/IHeap.h>
#include <xdc/runtime/System.h>
#include <xdc/runtime/Memory.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/heaps/HeapBuf.h>
#include <ti/sysbios/heaps/HeapMem.h>
#include <ti/sysbios/family/c64p/Hwi.h>
#include <ti/sysbios/family/c64p/EventCombiner.h>
#include <ti/sysbios/family/c66/Cache.h>
/* IPC includes */
#include <ti/ipc/GateMP.h>
#include <ti/ipc/Ipc.h>
#include <ti/ipc/ListMP.h>
#include <ti/ipc/SharedRegion.h>
#include <ti/ipc/MultiProc.h>
#include <xdc/cfg/global.h>
/* SRIO Driver Include File. */
#include <ti/drv/srio/srio_drv.h>
/* CPPI/QMSS Include Files. */
#include <ti/drv/cppi/cppi_drv.h>
#include <ti/drv/qmss/qmss_drv.h>
#include <ti/drv/qmss/qmss_firmware.h>
/* CSL Include Files */
#include <ti/csl/csl_chip.h>
#include <ti/csl/csl_cacheAux.h>
#include <ti/csl/csl_psc.h>
#include <ti/csl/csl_pscAux.h>
#include <ti/csl/csl_semAux.h>
/**********************************************************************
************************** LOCAL Definitions *************************
**********************************************************************/
#define NUM_HOST_DESC 32
#define SIZE_HOST_DESC 48
#define SRIO_MAX_MTU 256
/* Defines the core number responsible for system initialization. */
#define CORE_SYS_INIT 1
/* Number of cores for which the test is being executed. */
#define NUM_CORES 4
/* SRIO Application Hardware Semaphore. */
#define SRIO_APP_HW_SEM 5
/**********************************************************************
************************** Global Variables **************************
**********************************************************************/
/* Memory used for the descriptors. */
#pragma DATA_ALIGN (host_region, 16)
Uint8 host_region[NUM_HOST_DESC * SIZE_HOST_DESC];
Qmss_InitCfg qmssInitConfig;
/* Global Varialble which keeps track of the core number executing the
* application. */
UInt32 coreNum = 0xFFFF;
#pragma DATA_ALIGN (isSRIOInitialized, 128)
#pragma DATA_SECTION (isSRIOInitialized, ".srioSharedMem");
volatile Uint32 isSRIOInitialized = 0;
#pragma DATA_ALIGN (isSRIOSocketsCreated, 128)
#pragma DATA_SECTION (isSRIOSocketsCreated, ".srioSharedMem");
volatile Uint32 isSRIOSocketsCreated = 0;
/* Memory used for the accumulator list. */
#pragma DATA_ALIGN (gHiPriAccumList, 16)
UInt32 gHiPriAccumList[32];
/* These are the device identifiers used used in the TEST Application */
const uint32_t DEVICE_ID1_16BIT = 0xBEEF;
const uint32_t DEVICE_ID1_8BIT = 0xAB;
const uint32_t DEVICE_ID2_16BIT = 0x4560;
const uint32_t DEVICE_ID2_8BIT = 0xCD;
const uint32_t DEVICE_ID3_16BIT = 0x1234;
const uint32_t DEVICE_ID3_8BIT = 0x12;
const uint32_t DEVICE_ID4_16BIT = 0x5678;
const uint32_t DEVICE_ID4_8BIT = 0x56;
/**********************************************************************
************************* Extern Definitions *************************
**********************************************************************/
extern UInt32 malloc_counter;
extern UInt32 free_counter;
extern int32_t SrioDevice_init (void);
extern Void* Osal_srioDataBufferMalloc(UInt32 numBytes);
/* QMSS device specific configuration */
extern Qmss_GlobalConfigParams qmssGblCfgParams;
/* CPPI device specific configuration */
extern Cppi_GlobalConfigParams cppiGblCfgParams;
/* OSAL Data Buffer Memory Initialization. */
extern int32_t Osal_dataBufferInitMemory(uint32_t dataBufferSize);
/**********************************************************************
************************ SRIO TEST FUNCTIONS *************************
**********************************************************************/
/**
* @b Description
* @n
* Utility function which converts a local address to global.
*
* @param[in] addr
* Local address to be converted
*
* @retval
* Global Address
*/
static UInt32 l2_global_address (Uint32 addr)
{
UInt32 corenum;
/* Get the core number. */
corenum = CSL_chipReadReg(CSL_CHIP_DNUM);
/* Compute the global address. */
return (addr + (0x10000000 + (corenum*0x1000000)));
}
/**
* @b Description
* @n
* Utility function that is required by the IPC module to set the proc Id.
* The proc Id is set via this function instead of hard coding it in the .cfg file
*
* @retval
* Not Applicable.
*/
Void myStartupFxn (Void)
{
MultiProc_setLocalId (CSL_chipReadReg (CSL_CHIP_DNUM));
}
/**
* @b Description
* @n
* This function enables the power/clock domains for SRIO.
*
* @retval
* Not Applicable.
*/
static Int32 enable_srio (void)
{
#ifndef SIMULATOR_SUPPORT
/* SRIO power domain is turned OFF by default. It needs to be turned on before doing any
* SRIO device register access. This not required for the simulator. */
/* Set SRIO Power domain to ON */
CSL_PSC_enablePowerDomain (CSL_PSC_PD_SRIO);
/* Enable the clocks too for SRIO */
CSL_PSC_setModuleNextState (CSL_PSC_LPSC_SRIO, PSC_MODSTATE_ENABLE);
/* Start the state transition */
CSL_PSC_startStateTransition (CSL_PSC_PD_SRIO);
/* Wait until the state transition process is completed. */
while (!CSL_PSC_isStateTransitionDone (CSL_PSC_PD_SRIO));
/* Return SRIO PSC status */
if ((CSL_PSC_getPowerDomainState(CSL_PSC_PD_SRIO) == PSC_PDSTATE_ON) &&
(CSL_PSC_getModuleState (CSL_PSC_LPSC_SRIO) == PSC_MODSTATE_ENABLE))
{
/* SRIO ON. Ready for use */
return 0;
}
else
{
/* SRIO Power on failed. Return error */
return -1;
}
#else
/* PSC is not supported on simulator. Return success always */
return 0;
#endif
}
/**
* @b Description
* @n
* System Initialization Code. This is added here only for illustrative
* purposes and needs to be invoked once during initialization at
* system startup.
*
* @retval
* Success - 0
* @retval
* Error - <0
*/
static Int32 system_init (Void)
{
Int32 result;
Qmss_MemRegInfo memRegInfo;
/* Initialize the QMSS Configuration block. */
memset (&qmssInitConfig, 0, sizeof (Qmss_InitCfg));
/* Set up the linking RAM. Use the internal Linking RAM.
* LLD will configure the internal linking RAM address and maximum internal linking RAM size if
* a value of zero is specified. Linking RAM1 is not used */
qmssInitConfig.linkingRAM0Base = 0;
qmssInitConfig.linkingRAM0Size = 0;
qmssInitConfig.linkingRAM1Base = 0;
qmssInitConfig.maxDescNum = NUM_HOST_DESC;
#ifdef xdc_target__bigEndian
System_printf("Using Big Endian QMSS\n");
qmssInitConfig.pdspFirmware[0].pdspId = Qmss_PdspId_PDSP1;
qmssInitConfig.pdspFirmware[0].firmware = &acc48_be;
qmssInitConfig.pdspFirmware[0].size = sizeof (acc48_be);
#else
System_printf("Using Little Endian QMSS\n");
qmssInitConfig.pdspFirmware[0].pdspId = Qmss_PdspId_PDSP1;
qmssInitConfig.pdspFirmware[0].firmware = &acc48_le;
qmssInitConfig.pdspFirmware[0].size = sizeof (acc48_le);
#endif
/* Initialize Queue Manager Sub System */
result = Qmss_init (&qmssInitConfig, &qmssGblCfgParams);
if (result != QMSS_SOK)
{
System_printf ("Error initializing Queue Manager SubSystem error code : %d\n", result);
return -1;
}
/* Start the QMSS. */
if (Qmss_start() != QMSS_SOK)
{
System_printf ("Error: Unable to start the QMSS\n");
return -1;
}
/* Memory Region 0 Configuration */
memRegInfo.descBase = (UInt32 *)l2_global_address((UInt32)host_region);
memRegInfo.descSize = SIZE_HOST_DESC;
memRegInfo.descNum = NUM_HOST_DESC;
memRegInfo.manageDescFlag = Qmss_ManageDesc_MANAGE_DESCRIPTOR;
memRegInfo.memRegion = Qmss_MemRegion_MEMORY_REGION_NOT_SPECIFIED;
/* Initialize and inset the memory region. */
result = Qmss_insertMemoryRegion (&memRegInfo);
if (result < QMSS_SOK)
{
System_printf ("Error inserting memory region: %d\n", result);
return -1;
}
/* Initialize CPPI CPDMA */
result = Cppi_init (&cppiGblCfgParams);
if (result != CPPI_SOK)
{
System_printf ("Error initializing Queue Manager SubSystem error code : %d\n", result);
return -1;
}
/* CPPI and Queue Manager are initialized. */
System_printf ("Debug: Queue Manager and CPPI are initialized.\n");
System_printf ("Debug: Host Region 0x%x\n", host_region);
return 0;
}
/**
* @b Description
* @n
* The function tests multicore
*
* @param[in] hSrioDrv
* Handle to the SRIO driver
*
* @retval
* Success - 0
* @retval
* Error - <0
*/
static Int32 test_multicore (Srio_DrvHandle hSrioDrv)
{
Srio_SockHandle srioSocket;
Srio_SockBindAddrInfo bindInfo;
UInt8* txData;
Srio_SockAddrInfo to;
Srio_SockAddrInfo from;
UInt16 idx;
Int32 num_bytes;
UInt8* ptr_rxDataPayload;
Int32 sendToCore;
Int32 recvFromCore;
Srio_DrvBuffer hDrvBuffer;
UInt32 allocatedLen;
UInt16 coreDeviceID[NUM_CORES];
System_printf ("**********************************************\n");
System_printf ("******** Multicore Testing (Core %d) *********\n", coreNum);
System_printf ("**********************************************\n");
/* Open SRIO Socket in Blocking Mode */
srioSocket = Srio_sockOpen (hSrioDrv, Srio_SocketType_TYPE11, TRUE);
if (srioSocket == NULL)
{
System_printf ("Error: Unable to open socket1\n");
return -1;
}
/* Initialize the core Device IDs: Each core has a seperate device ID. */
coreDeviceID[0] = DEVICE_ID1_16BIT;
coreDeviceID[1] = DEVICE_ID2_16BIT;
coreDeviceID[2] = DEVICE_ID3_16BIT;
coreDeviceID[3] = DEVICE_ID4_16BIT;
/* Initialize the core bindings; we use the same mailbox & letter identifiers. */
bindInfo.type11.tt = TRUE;
bindInfo.type11.id = coreDeviceID[coreNum];
bindInfo.type11.letter = 2;
bindInfo.type11.mbox = 3;
bindInfo.type11.segMap = 0x0;
/* Bind the SRIO socket */
if (Srio_sockBind (srioSocket, &bindInfo) < 0)
{
System_printf ("Error: socket1 bind failed\n");
return -1;
}
/* Get a transmit buffer from the SRIO Driver. */
hDrvBuffer = Srio_allocTransmitBuffer(hSrioDrv, &txData, &allocatedLen);
if (hDrvBuffer == NULL)
{
System_printf ("Error: Producer Memory Allocation failed.\n");
return -1;
}
/* Create the transmit data payload. */
for (idx = 0; idx < 100; idx++)
txData[idx] = 0xA0 | coreNum;
/* The global variable is a shared resource which is being accessed from multiple cores.
* So here we need to protect it and ensure that there is only 1 core which is accessing
* it at a time. We use a Hardware Semaphore to protect this. */
while ((CSL_semAcquireDirect (SRIO_APP_HW_SEM)) == 0);
/* Invalidate the cache and make sure you get the latest from the memory. */
CACHE_invL1d ((void *) &isSRIOSocketsCreated, 128, CACHE_WAIT);
/* The core has created the sockets:*/
isSRIOSocketsCreated++;
/* The SRIO Socket has been created. Writeback the contents to the cache. */
CACHE_wbL1d ((void *) &isSRIOSocketsCreated, 128, CACHE_WAIT);
/* Release the hardware semaphore. */
CSL_semReleaseSemaphore (SRIO_APP_HW_SEM);
/* We can proceed with the data transmission & reception tests only after all the
* cores have created and bound their SRIO sockets. This is a simple counter running
* in shared memory which allows us to SYNC up the socket creation. Wait till all the
* cores have created the sockets */
while (isSRIOSocketsCreated != NUM_CORES)
CACHE_invL1d ((void *) &isSRIOSocketsCreated, 128, CACHE_WAIT);
System_printf ("------------------------------------------------------\n");
/* Is this the starting core? */
if (coreNum == 1)
{
/* Starting Core: This is a special case because unlike the other cores; this initiates
* the whole test cycle by sending the first packet. */
sendToCore = coreNum + 1;
recvFromCore = coreNum - 1;
if (recvFromCore < 0)
recvFromCore = NUM_CORES-1;
/* Send the data out. */
to.type11.tt = TRUE;
to.type11.id = coreDeviceID[sendToCore];
to.type11.letter = 2;
to.type11.mbox = 3;
/* Send the data out from the producer core to the consumer core. */
if (Srio_sockSend (srioSocket, hDrvBuffer, 100, &to) < 0)
{
System_printf ("Error: SRIO Socket send failed\n");
return -1;
}
/* Debug Message */
System_printf ("Debug(Core %d): Successfully sent data to ID:0x%x\n", coreNum, to.type11.id);
/* CORE0: Wait for data to arrive from NUM_CORES-1 */
System_printf ("Debug(Core %d): Waiting for data to arrive 0x%x\n", coreNum, bindInfo.type11.id);
/* Receive the data. */
num_bytes = Srio_sockRecv (srioSocket, (Srio_DrvBuffer*)&ptr_rxDataPayload, &from);
if (num_bytes > 0)
{
/* Make sure that the data was received from the producer core */
if (from.type11.id != coreDeviceID[recvFromCore])
{
System_printf ("Error: Invalid source id 0x%x Expected 0x%x\n", from.type11.id, coreDeviceID[recvFromCore]);
return -1;
}
/* Received and Transmitted packet length match. Payload verification */
for (idx = 0; idx < 100; idx++)
{
if (ptr_rxDataPayload[idx] != (0xA0 | recvFromCore))
{
System_printf ("Error: Receive Data Payload verification failed @ index %d\n", idx);
return -1;
}
}
System_printf ("Debug(Core %d): Successfully received %d bytes\n", coreNum, num_bytes);
/* Cleanup the received data payload. */
Srio_freeRxDrvBuffer(srioSocket, (Srio_DrvBuffer)ptr_rxDataPayload);
}
else
{
/* Error: In receiving data */
System_printf ("Error: Unable to receive data %d\n", num_bytes);
return -1;
}
}
else
{
/* Any other core besides the starting core will initally wait for data to arrive */
sendToCore = (coreNum + 1) % NUM_CORES;
recvFromCore = coreNum - 1;
if (recvFromCore < 0)
recvFromCore = NUM_CORES-1;
System_printf ("Debug(Core %d): Waiting for data to arrive 0x%x\n", coreNum, bindInfo.type11.id);
/* Receive the data. */
num_bytes = Srio_sockRecv (srioSocket, (Srio_DrvBuffer*)&ptr_rxDataPayload, &from);
if (num_bytes > 0)
{
/* Make sure that the data was received from the producer core */
if (from.type11.id != coreDeviceID[recvFromCore])
{
System_printf ("Error: Invalid source id 0x%x Expected 0x%x\n", from.type11.id, coreDeviceID[recvFromCore]);
return -1;
}
/* Received and Transmitted packet length match. Payload verification */
for (idx = 0; idx < 100; idx++)
{
if (ptr_rxDataPayload[idx] != (0xA0 | recvFromCore))
{
System_printf ("Error: Receive Data Payload verification failed @ index %d\n", idx);
return -1;
}
}
System_printf ("Debug(Core %d): Successfully received %d bytes\n", coreNum, num_bytes);
/* Cleanup the received data payload. */
Srio_freeRxDrvBuffer(srioSocket, (Srio_DrvBuffer)ptr_rxDataPayload);
}
else
{
/* Error: In receiving data */
System_printf ("Error: Unable to receive data %d\n", num_bytes);
return -1;
}
/* CoreX: Sends outs the packet to CoreX+1. */
to.type11.tt = TRUE;
to.type11.id = coreDeviceID[sendToCore];
to.type11.letter = 2;
to.type11.mbox = 3;
/* Send the data out from the producer core to the consumer core. */
if (Srio_sockSend (srioSocket, hDrvBuffer, 100, &to) < 0)
{
System_printf ("Error: SRIO Socket send failed\n");
return -1;
}
System_printf ("Debug(Core %d): Successfully sent data to ID:0x%x\n", coreNum, coreDeviceID[sendToCore]);
}
/* Close the sockets */
Srio_sockClose (srioSocket);
/* We are done with the test. */
System_printf ("Debug(Core %d): Multicore Test Passed\n", coreNum);
return 0;
}
/**
* @b Description
* @n
* This is the Multicore Test task
*
* @retval
* Not Applicable.
*/
static Void multicoreTestTask(UArg arg0, UArg arg1)
{
Srio_DrvConfig cfg;
Srio_DrvHandle hSrioDriver;
UInt8 isAllocated;
/* Initialize the OSAL Data Buffer */
if (Osal_dataBufferInitMemory(SRIO_MAX_MTU) < 0)
return;
/* Initialize the SRIO Driver Configuration. */
memset ((Void *)&cfg, 0, sizeof(Srio_DrvConfig));
/* Setup the SRIO Driver Managed Configuration. */
cfg.bAppManagedConfig = FALSE;
/* Driver Managed: Receive Configuration */
cfg.u.drvManagedCfg.bIsRxCfgValid = 1;
cfg.u.drvManagedCfg.rxCfg.rxMemRegion = Qmss_MemRegion_MEMORY_REGION0;
cfg.u.drvManagedCfg.rxCfg.numRxBuffers = 4;
cfg.u.drvManagedCfg.rxCfg.rxMTU = SRIO_MAX_MTU;
/* Accumulator Configuration. */
{
int32_t coreToQueueSelector[4];
/* This is the table which maps the core to a specific receive queue. */
coreToQueueSelector[0] = 704;
coreToQueueSelector[1] = 705;
coreToQueueSelector[2] = 706;
coreToQueueSelector[3] = 707;
/* Since we are programming the accumulator we want this queue to be a HIGH PRIORITY Queue */
cfg.u.drvManagedCfg.rxCfg.rxCompletionQueue = Qmss_queueOpen (Qmss_QueueType_HIGH_PRIORITY_QUEUE,
coreToQueueSelector[coreNum],
&isAllocated);
if (cfg.u.drvManagedCfg.rxCfg.rxCompletionQueue < 0)
{
System_printf ("Error: Unable to open the SRIO Receive Completion Queue\n");
return;
}
/* Accumulator Configuration is VALID. */
cfg.u.drvManagedCfg.rxCfg.bIsAccumlatorCfgValid = 1;
/* Accumulator Configuration. */
cfg.u.drvManagedCfg.rxCfg.accCfg.channel = coreNum;
cfg.u.drvManagedCfg.rxCfg.accCfg.command = Qmss_AccCmd_ENABLE_CHANNEL;
cfg.u.drvManagedCfg.rxCfg.accCfg.queueEnMask = 0;
cfg.u.drvManagedCfg.rxCfg.accCfg.queMgrIndex = coreToQueueSelector[coreNum];
cfg.u.drvManagedCfg.rxCfg.accCfg.maxPageEntries = 2;
cfg.u.drvManagedCfg.rxCfg.accCfg.timerLoadCount = 0;
cfg.u.drvManagedCfg.rxCfg.accCfg.interruptPacingMode = Qmss_AccPacingMode_LAST_INTERRUPT;
cfg.u.drvManagedCfg.rxCfg.accCfg.listEntrySize = Qmss_AccEntrySize_REG_D;
cfg.u.drvManagedCfg.rxCfg.accCfg.listCountMode = Qmss_AccCountMode_ENTRY_COUNT;
cfg.u.drvManagedCfg.rxCfg.accCfg.multiQueueMode = Qmss_AccQueueMode_SINGLE_QUEUE;
/* Initialize the accumulator list memory */
memset ((Void *)&gHiPriAccumList[0], 0, sizeof(gHiPriAccumList));
cfg.u.drvManagedCfg.rxCfg.accCfg.listAddress = l2_global_address((UInt32)&gHiPriAccumList[0]);
}
/* Driver Managed: Transmit Configuration */
cfg.u.drvManagedCfg.bIsTxCfgValid = 1;
cfg.u.drvManagedCfg.txCfg.txMemRegion = Qmss_MemRegion_MEMORY_REGION0;
cfg.u.drvManagedCfg.txCfg.numTxBuffers = 4;
cfg.u.drvManagedCfg.txCfg.txMTU = SRIO_MAX_MTU;
/* Start the SRIO Driver */
hSrioDriver = Srio_start(&cfg);
if (hSrioDriver == NULL)
{
System_printf ("Error: SRIO Driver Start Failed\n");
return;
}
/* SRIO Driver is operational at this time. */
System_printf ("Debug: SRIO Driver has been started Instance Handle 0x%p\n", hSrioDriver);
/* Hook up the SRIO interrupts with the core. */
EventCombiner_dispatchPlug (48, (EventCombiner_FuncPtr)Srio_rxCompletionIsr, (UArg)hSrioDriver, TRUE);
EventCombiner_enableEvent(48);
/* Map the event id to hardware interrupt 8. */
Hwi_eventMap(8, 48);
/* Enable interrupt 8. */
Hwi_enableInterrupt(8);
/* SRIO Driver is operational at this time. */
System_printf ("Debug: SRIO Driver ISR has been registered\n");
/* Run the Multicore Test */
if (test_multicore (hSrioDriver) < 0)
{
System_printf ("Error: Multicore Tests failed\n");
return;
}
/* Print out the Malloc & Free Counter */
System_printf ("Debug(Core %d): Allocation Counter : %d\n", coreNum, malloc_counter);
System_printf ("Debug(Core %d): Free Counter : %d\n", coreNum, free_counter);
/* Check if there is a memory leak? Since we dont implement the DEINIT API
* there are 'cfg.numRxDesc' and 'cfg.numTxDesc' buffers always allocated for
* the SRIO Driver. 1 allocation is there for the Driver Instance
* Take this into account while we check for leaks? */
if ((cfg.u.drvManagedCfg.rxCfg.numRxBuffers + cfg.u.drvManagedCfg.txCfg.numTxBuffers + free_counter + 1 ) !=
malloc_counter)
{
System_printf ("Error: Memory Leak Detected\n");
Task_exit();
}
/* Control comes here implies that all testing passed. */
System_printf ("Debug(Core %d): Multicore Example successful.\n", coreNum);
return;
}
/**
* @b Description
* @n
* Entry point for the example
*
* @retval
* Not Applicable.
*/
Void main(Void)
{
Task_Params taskParams;
/* Get the core number. */
coreNum = CSL_chipReadReg (CSL_CHIP_DNUM);
System_printf ("****************************************************\n");
System_printf ("****** Multicore Loopback Testing (Core %d) *******\n", coreNum);
System_printf ("****************************************************\n");
/* Initialize the heap in shared memory. Using IPC module to do that */
Ipc_start();
/* Initialize the system only if the core was configured to do so. */
if (coreNum == CORE_SYS_INIT)
{
System_printf ("Debug(Core %d): System Initialization for CPPI & QMSS\n", coreNum);
/* System Initialization */
if (system_init() < 0)
return;
/* Power on SRIO peripheral before using it */
if (enable_srio () < 0)
{
System_printf ("Error: SRIO PSC Initialization Failed\n");
return;
}
/* Device Specific SRIO Initializations: This should always be called before
* initializing the SRIO Driver. */
if (SrioDevice_init() < 0)
return;
/* Initialize the SRIO Driver */
if (Srio_init () < 0)
{
System_printf ("Error: SRIO Driver Initialization Failed\n");
return;
}
/* SRIO Driver is operational at this time. */
System_printf ("Debug(Core %d): SRIO Driver has been initialized\n", coreNum);
/* Write to the SHARED memory location at this point in time. The other cores cannot execute
* till the SRIO Driver is up and running. */
isSRIOInitialized = 1;
/* The SRIO IP block has been initialized. We need to writeback the cache here because it will
* ensure that the rest of the cores which are waiting for SRIO to be initialized would now be
* woken up. */
// CACHE_wbL1d ((void *) &isSRIOInitialized, 128, CACHE_WAIT);
Cache_wb ((void *) &isSRIOInitialized, 4, Cache_Type_L1D, TRUE);
}
else
{
/* TODO: Testing this.... */
System_printf ("Debug(Core %d): Waiting for SRIO to be initialized.\n", coreNum);
/* All other cores loop around forever till the SRIO is up and running.
* We need to invalidate the cache so that we always read this from the memory. */
// while (isSRIOInitialized == 0)
// CACHE_invL1d ((void *) &isSRIOInitialized, 128, CACHE_WAIT);
while (isSRIOInitialized == 0)
{
Cache_inv ((void *) &isSRIOInitialized, 4, Cache_Type_L1D, TRUE);
}
System_printf("Debug(Core %d): SRIO Initialized.\n",coreNum);
/* Start the QMSS. */
if (Qmss_start() != QMSS_SOK)
{
System_printf ("Error: Unable to start the QMSS\n");
return;
}
System_printf ("Debug(Core %d): SRIO can now be used.\n", coreNum);
}
/* Create the Multicore Test Task. */
Task_Params_init(&taskParams);
Task_create(multicoreTestTask, &taskParams, NULL);
/* Start the BIOS */
BIOS_start();
}