#include #include #include #include #include #include #include #include #include #define DEFAULT_CACHE_WAIT CACHE_WAIT #define CACHE_PRE_OP_STEPS \ unsigned intStatus = _disable_interrupts(); #define CACHE_POST_OP_STEPS \ asm(" MFENCE "); \ asm(" NOP "); asm(" NOP "); asm(" NOP "); asm(" NOP "); \ asm(" NOP "); asm(" NOP "); asm(" NOP "); asm(" NOP "); \ asm(" NOP "); asm(" NOP "); asm(" NOP "); asm(" NOP "); \ asm(" NOP "); asm(" NOP "); asm(" NOP "); asm(" NOP "); \ _restore_interrupts(intStatus); #define ERRATA_CACHE_invAllL1dWait() #define ERRATA_CACHE_invAllL1d(wait) { \ CACHE_PRE_OP_STEPS \ CACHE_invAllL1d(DEFAULT_CACHE_WAIT); \ CACHE_POST_OP_STEPS \ } #define ERRATA_CACHE_wbAllL1dWait() #define ERRATA_CACHE_wbAllL1d(wait) { \ CACHE_PRE_OP_STEPS \ CACHE_wbAllL1d(DEFAULT_CACHE_WAIT); \ CACHE_POST_OP_STEPS \ } #define ERRATA_CACHE_wbInvAllL1dWait() #define ERRATA_CACHE_wbInvAllL1d(wait) { \ CACHE_PRE_OP_STEPS \ CACHE_wbInvAllL1d(DEFAULT_CACHE_WAIT); \ CACHE_POST_OP_STEPS \ } #define ERRATA_CACHE_invL1dWait() #define ERRATA_CACHE_invL1d(block,size,wait) { \ CACHE_PRE_OP_STEPS \ CACHE_invL1d(block,size,DEFAULT_CACHE_WAIT); \ CACHE_POST_OP_STEPS \ } #define ERRATA_CACHE_wbL1dWait() #define ERRATA_CACHE_wbL1d(block,size,wait) { \ CACHE_PRE_OP_STEPS \ CACHE_wbL1d(block,size,DEFAULT_CACHE_WAIT); \ CACHE_POST_OP_STEPS \ } #define ERRATA_CACHE_wbInvL1dWait() #define ERRATA_CACHE_wbInvL1d(block,size,wait) { \ CACHE_PRE_OP_STEPS \ CACHE_wbInvL1d(block,size,DEFAULT_CACHE_WAIT); \ CACHE_POST_OP_STEPS \ } #define ERRATA_CACHE_wbL2Wait() #define ERRATA_CACHE_wbL2(block,size,wait) { \ CACHE_PRE_OP_STEPS \ CACHE_wbL2(block,size,DEFAULT_CACHE_WAIT); \ CACHE_POST_OP_STEPS \ } #define ERRATA_CACHE_invL2Wait() #define ERRATA_CACHE_invL2(block,size,wait) { \ CACHE_PRE_OP_STEPS \ CACHE_invL2(block,size,DEFAULT_CACHE_WAIT); \ CACHE_POST_OP_STEPS \ } #define ERRATA_CACHE_wbInvL2Wait() #define ERRATA_CACHE_wbInvL2(block,size,wait) { \ CACHE_PRE_OP_STEPS \ CACHE_wbInvL2(block,size,DEFAULT_CACHE_WAIT); \ CACHE_POST_OP_STEPS \ } #define ERRATA_CACHE_wbAllL2Wait() #define ERRATA_CACHE_wbAllL2(wait) { \ CACHE_PRE_OP_STEPS \ CACHE_wbAllL2(DEFAULT_CACHE_WAIT); \ CACHE_POST_OP_STEPS \ } #define ERRATA_CACHE_invAllL2Wait() #define ERRATA_CACHE_invAllL2(wait) { \ CACHE_PRE_OP_STEPS \ CACHE_invAllL2(DEFAULT_CACHE_WAIT); \ CACHE_POST_OP_STEPS \ } #define ERRATA_CACHE_wbInvAllL2Wait() #define ERRATA_CACHE_wbInvAllL2(wait) { \ CACHE_PRE_OP_STEPS \ CACHE_wbInvAllL2(DEFAULT_CACHE_WAIT); \ CACHE_POST_OP_STEPS \ } #define PLATFORM_ASSERT(x) do {printf("Assertion \"%s\" failed at line %d in %s\n", x, __LINE__, __FILE__); *(int*)0x00000000 = 0;} while(0) #define ASSERT(message, assertion) do { if(!(assertion)) PLATFORM_ASSERT(message); } while(0) typedef struct _wordstruct { unsigned WORD8[8]; } wordstruct; static void ti_cache_init() { unsigned char mar; CACHE_setL1PSize(CACHE_L1_32KCACHE); // set L1 to max // SPRU871J 3.4.3.1 CACHE_setL1DSize(CACHE_L1_32KCACHE); // set L1 to max // SPRU871J 3.4.3.1 // MAR0 - MAR15 are READ-ONLY // MAR16 - MAR127 are for addresses from 0x10000000 - 0x7FFFFFFF for (mar = 16; mar < 128; mar++) CACHE_disableCaching(mar); // 512 MB = 0x20000000, correspond to MAR128 to MAR159: 0x80000000 - 0x9FFFFFFF for (; mar < 160; mar++) CACHE_enableCaching(mar); // Disable ALL OTHER addresses for (; mar < 255; mar++) CACHE_disableCaching(mar); CACHE_disableCaching(mar); CACHE_setL2Size(CACHE_256KCACHE); // L2 cache size to 256k (maximum) // SPRU871J 4.4.5 } // For some reason, TCC code above 15 DOES NOT SHOW UP IN IPR (Interrupt Pending Register) #define EDMA_TCC_DESIRED 15 // UNCOMMENT THE FOLLOWING LINE IF MANUALLY ADJUST CACHE_invL2 to CACHE LINE ONLY #define DO_CACHE_INVALID_FULL_LINE #define USE_ERRATA_CACHE_FUNCTIONS void main(void) { CSL_Edma3Handle dmaHandle; CSL_Edma3Obj edmaObj; CSL_Edma3HwSetup setup; CSL_Edma3HwDmaChannelSetup dmahwSetup[64]; // 64 DMA + 8 QDMA for tpcc1 and tpcc2 CSL_Edma3HwQdmaChannelSetup qdmahwSetup[8]; CSL_Edma3ChannelAttr chAttr; CSL_Edma3ChannelObj chObj; CSL_Edma3ChannelHandle hChannel; CSL_Edma3ParamHandle hParam; CSL_Edma3ParamSetup paramSetup; CSL_Edma3ChannelErr chErr; CSL_InstNum edmaInstance = 0; wordstruct *words; CSL_Status cslStatus; unsigned index, u32val, ddr3Addr; ti_cache_init(); cslStatus = CSL_edma3Init(NULL); ASSERT("CSL_edma3Init returns CSL_SOK", CSL_SOK == cslStatus); dmaHandle = CSL_edma3Open(&edmaObj, edmaInstance, NULL, &cslStatus); ASSERT("CSL_edma3Open returns CSL_SOK", CSL_SOK == cslStatus && dmaHandle != NULL); setup.dmaChaSetup = dmahwSetup; setup.qdmaChaSetup = qdmahwSetup; // 512 param for 64 DMA + 8 QDMA => 7 param per u32val = 0; for (index = 0; index < 64; index++) { dmahwSetup[index].que = index & 7; dmahwSetup[index].paramNum = u32val; u32val += 7; } for (index = 0; index < 8; index++) { qdmahwSetup[index].que = index & 7; qdmahwSetup[index].paramNum = u32val; qdmahwSetup[index].triggerWord = 7; u32val += 7; } cslStatus = CSL_edma3HwSetup(dmaHandle, &setup); ASSERT("CSL_edma3HwSetup returns CSL_SOK", CSL_SOK == cslStatus); chAttr.regionNum = CSL_EDMA3_REGION_GLOBAL; chAttr.chaNum = 0; hChannel = CSL_edma3ChannelOpen(&chObj, edmaInstance, &chAttr, &cslStatus); ASSERT("CSL_edma3ChannelOpen returns CSL_SOK", CSL_SOK == cslStatus && hChannel != NULL); hParam = CSL_edma3GetParamHandle(hChannel, 0, &cslStatus); ASSERT("CSL_edma3GetParamHandle returns CSL_SOK", CSL_SOK == cslStatus && hParam != NULL); cslStatus = CSL_edma3HwChannelControl(hChannel, CSL_EDMA3_CMD_CHANNEL_CLEAR , NULL); ASSERT("CSL_edma3HwChannelControl(CLEAR) returns CSL_SOK", CSL_SOK == cslStatus); cslStatus = CSL_edma3HwChannelControl(hChannel, CSL_EDMA3_CMD_CHANNEL_CLEARERR, &chErr); ASSERT("CSL_edma3HwChannelControl(CLEARERR) returns CSL_SOK", CSL_SOK == cslStatus); cslStatus = CSL_edma3HwChannelControl(hChannel, CSL_EDMA3_CMD_CHANNEL_ENABLE, NULL); ASSERT("CSL_edma3HwChannelControl(ENABLE) returns CSL_SOK", CSL_SOK == cslStatus); CSL_edma3ClearLoPendingInterrupts(dmaHandle, CSL_EDMA3_REGION_GLOBAL, 0xFFFFFFFF); CSL_edma3ClearHiPendingInterrupts(dmaHandle, CSL_EDMA3_REGION_GLOBAL, 0xFFFFFFFF); CSL_edma3InterruptLoDisable(dmaHandle, CSL_EDMA3_REGION_GLOBAL, 0xFFFFFFFF); CSL_edma3InterruptHiDisable(dmaHandle, CSL_EDMA3_REGION_GLOBAL, 0xFFFFFFFF); memset((void*)0x80000200, 0, 512 << 5); #ifdef USE_ERRATA_CACHE_FUNCTIONS ERRATA_CACHE_wbInvL2((void*)0x80000200, 512 << 5, CACHE_WAIT); #else CACHE_wbInvL2((void*)0x80000200, 512 << 5, CACHE_WAIT); #endif for (index = 0; index < 512; index++) { ddr3Addr = 0x80000200 + (index << 5); paramSetup.option = CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS, CSL_EDMA3_TCCH_DIS, CSL_EDMA3_ITCINT_DIS, CSL_EDMA3_TCINT_EN, EDMA_TCC_DESIRED, CSL_EDMA3_TCC_NORMAL, CSL_EDMA3_FIFOWIDTH_NONE, CSL_EDMA3_STATIC_DIS, CSL_EDMA3_SYNC_A, CSL_EDMA3_ADDRMODE_INCR, CSL_EDMA3_ADDRMODE_INCR); paramSetup.srcAddr = 0x90000000; paramSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(32,1); paramSetup.dstAddr = ddr3Addr; paramSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(1,1); paramSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(CSL_EDMA3_LINK_NULL,0); paramSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,1); paramSetup.cCnt = 1; cslStatus = CSL_edma3ParamSetup(hParam, ¶mSetup); ASSERT("CSL_edma3ParamSetup returns CSL_SOK", CSL_SOK == cslStatus); words = (wordstruct*)0x90000000; words->WORD8[0] = (index << 16) | index; words->WORD8[1] = index + 0x10; words->WORD8[2] = index + 0x20; words->WORD8[3] = index + 0x30; words->WORD8[4] = index + 0x40; words->WORD8[5] = index + 0x50; words->WORD8[6] = index + 0x60; words->WORD8[7] = index + 0x70; #ifdef USE_ERRATA_CACHE_FUNCTIONS ERRATA_CACHE_wbL2((void*)0x90000000, 0x20, CACHE_WAIT); #else CACHE_wbL2((void*)0x90000000, 0x20, CACHE_WAIT); #endif cslStatus = CSL_edma3HwChannelControl(hChannel, CSL_EDMA3_CMD_CHANNEL_SET, NULL); ASSERT("CSL_edma3HwChannelControl(SET) returns CSL_SOK", CSL_SOK == cslStatus); do { asm(" NOP "); asm(" NOP "); asm(" NOP "); asm(" NOP "); asm(" NOP "); asm(" NOP "); asm(" NOP "); asm(" NOP "); CSL_edma3GetLoPendingInterrupts(dmaHandle, CSL_EDMA3_REGION_GLOBAL, &u32val); if ((u32val & (1 << EDMA_TCC_DESIRED)) != 0) { CSL_edma3ClearLoPendingInterrupts(dmaHandle, CSL_EDMA3_REGION_GLOBAL, 0xFFFFFFFF); break; } } while (1); // Transfer not yet completed words = (wordstruct*)ddr3Addr; #ifdef DO_CACHE_INVALID_FULL_LINE #ifdef USE_ERRATA_CACHE_FUNCTIONS //ERRATA_CACHE_invL2((void*)(ddr3Addr & 0xFFFFFF80), 0x80, CACHE_WAIT); // Invalidate 128 bytes ERRATA_CACHE_wbInvL2((void*)(ddr3Addr), 0x20, CACHE_WAIT); // Writeback-invalidate 32 bytes #else CACHE_invL2((void*)(ddr3Addr & 0xFFFFFF80), 0x80, CACHE_WAIT); // Invalidate 128 bytes #endif #else #ifdef USE_ERRATA_CACHE_FUNCTIONS ERRATA_CACHE_invL2((void*)ddr3Addr , 32, CACHE_WAIT); // Invalidate 32 bytes #else CACHE_invL2((void*)ddr3Addr , 32, CACHE_WAIT); // Invalidate 32 bytes #endif #endif if (words->WORD8[6] != index + 0x60) { printf("At addr %08X + 6, index %u, expected %08X, got %08X\n", ddr3Addr, index, index + 0x60, words->WORD8[6]); ASSERT("Valid value", words->WORD8[6] == index + 0x60); } } cslStatus = CSL_edma3Close(dmaHandle); ASSERT("CSL_edma3Close returns CSL_SOK", CSL_SOK == cslStatus); }