This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

How to find which system interrupt triggered host interrupt?

Other Parts Discussed in Thread: SYSBIOS, TMS320C6678

Now I have the following problem when using CpIntc in sysbios for C6678. I configured each core to use a unique EDMA completion system interrupt by using region.  Since host interrupt can only uniquely mapped to hwi in cfg script, I mapped all of these system interrupts to the same host interrupt to avoid using too many hwi.  As a result, any of these system interrupts causes the plug getting called on all cores. When my dispatch plug gets called on a particular core, I cannot figure out which system interrupt triggered this host interrupt. From your code CpIntc.c, I understand that SECR cannot be used because that sysbios first clears system interrupt before calling the plug. I can use semaphore to figure out what is happening, but does CpIntc itself or any of your other package provide a way for finding out what system interrupt triggered the plug call?

By the way, I cannot use CpIntc module from CSL since I need to use GateMP.

 

Dongning

  • Dongning,

    I don't think I'm following what you are saying.  When you use CpIntc, you are plugging each System interrupt with a function and argument.  I assume you must be plugging all these EDMA completion system interrupts with the same function?  If so then you should be able to pass an argument to the function which uniquely identifies which system interrupt is being processed.

    I don't follow your last statement but I don't think you should be using CpIntc with CSL in the first place and I don't understand what the relationship between CpIntc and CSL have to do with GateMP?

    Judah

  • Hi Judah,

     

    Thank you very much for your reply.

     

    Yes, I plugged all these EDMA completion system interrupts with the same function.  Each core uses a unique EMDA channel with its own system interrupt. All of the system interrupts are mapped to the same host interrupt 0 which is mapped to HWI 4. For the plugged handler function, each core uses a unique argument value equal to its core ID. The following code illustrates the EDMA and CpIntc setup.

     

      m_hostInt = 0;

      int coreId = MultiProc_self();

      Int16 paramNum = 1 +  coreId;

      Uint8 channelNum = 1 + coreId;

      Int32 regionNum = 0 + coreId;

      CSL_Edma3Que edma3Que = edmaId ? (CSL_Edma3Que) (coreId & 3) : (CSL_Edma3Que) (coreId & 1);

      rc = m_edma->Initialize(paramNum, edmaId, channelNum, regionNum, edma3Que);

     

      CpIntc_FuncPtr handler = (CpIntc_FuncPtr) GetGlobalAddr(&EdmaCompletedTask);

      int region = coreId;

      int tpccInt = region < 0 ? CSL_INTC_EDMACC_GINT : (CSL_INTC_TPCCINT0 + region);

      m_sysInt = edmaIntc[edmaId][tpccInt];

      printf("edmaId(%d), m_intcId(%d): m_sysInt(%d) => m_hostInt(%d)\n", edmaId, m_intcId, m_sysInt, m_hostInt);

     

      CpIntc_disableSysInt(m_intcId, m_sysInt);

      CpIntc_mapSysIntToHostInt(m_intcId, m_sysInt, m_hostInt);

      CpIntc_dispatchPlug(m_sysInt, handler, coreId, true);

     

      CpIntc_enableHostInt(m_intcId, m_hostInt);

      CpIntc_enableSysInt(m_intcId, m_sysInt);

     

    In my test, I have 4 cores running setup as follows:

     

      int coreId = MultiProc_self();

      int setupCoreId = 0;

      if(coreId < 4)

      {

        SetupTrace(); // This will setup EDMA and CpIntc above

        if(coreId != setupCoreId) Task_sleep(100); // core 0 will create GateMP while other cores will open it.

        if((MultiProc_self() & 3) == (setupCoreId & 3))

        {

          TraceDbg(coreId, "TraceDbg %d\n", MultiProc_self()); // This will issue an EDMA and trigger the interrupt.

        }

        Task_sleep(200);

        printf("%08x\n", iFlags);

      }

     

    The plugged interrupt handler code is as follows:

     

    extern "C" void EdmaCompletedTask(UArg arg)

    {

      int coreId = MultiProc_self();

      if(coreId == (int) arg)

      {

        iFlags |= 1 << arg;

        CacheWbInv(&iFlags);

        gTraceQ->PostEdmaCompl(); // This will cause some task to handle the interrupt.

      }

    }

     

    With the above code, I get the following log from printf:

     

    [C66xx_0] edmaId(1), m_intcId(0): m_sysInt(8) => m_hostInt(0)

    [C66xx_1] edmaId(1), m_intcId(0): m_sysInt(9) => m_hostInt(0)

    [C66xx_2] edmaId(1), m_intcId(0): m_sysInt(10) => m_hostInt(0)

    [C66xx_3] edmaId(1), m_intcId(0): m_sysInt(11) => m_hostInt(0)

    [C66xx_0] dstMsg(0082cb38), m_dspSeqNum(0), m_sysInt(8)

    [C66xx_0] CTraceQ::TraceEdmaCompleted() - 0 core0

    [C66xx_1] CTraceQ::TraceEdmaCompleted() - 0 core1

    [C66xx_2] CTraceQ::TraceEdmaCompleted() - 0 core2

    [C66xx_3] CTraceQ::TraceEdmaCompleted() - 0 core3

    [C66xx_1] 00000002

    [C66xx_0] 00000001

    [C66xx_2] 00000004

    [C66xx_3] 00000008

     

    The last 4 lines of the log shows that one EDMA completion causes all handlers get called and they are called all with the argument values used in their setup. If they were called with argument value setup by the core that issued the EDMA request (in this example 0), I would be able to tell which system interrupt causes the interrupt triggered.

     

    As to using CpIntc from CSL with GateMp, I encountered some problem and was advised by this forum that I should use CpIntc from sysbios to make GateMp work. The following is the reply link:

     

    http://e2e.ti.com/support/dsp/c6000_multi-core_dsps/f/639/p/128907/461574.aspx#461574

     

    Could you now understand my problem?

     

    Dongning

  • Dongning,

    Thanks for the description.

    For issue #1.  Why are you passing the coreId as the argument to your ISR handler?  I don't think you need to do this since in general on C6678 MultiProc_self() = DNUM.  So you can just use the DNUM in your ISR handler and you don't need to pass this in as the argument.  You need to pass the system int number as the argument.  This is the only way you will know which system interrupt triggered the isr.  For example, we do this in our regression tests:

        CpIntc_mapSysIntToHostInt(0, 15, 8);                             // map system int 15 to host int 8 
        CpIntc_dispatchPlug(15, &event15Fxn, 15, TRUE);     // plug system int 15 with function and argument = system int #

    For issue #2.  CpIntc and GateMP are totally orthogonal to each other.  CpIntc is dealing with Interrupts and GateMP is dealing with Hardware Sempahores on the C6678.  I think the issue here is that there could be some contention for resources between CSL and GateMP and that's probably why you were steered to not use CSL but instead to use CpIntc in place of CSL.  Not being familiar with CSL, I don't know what resources its grabbing.  I know that GateMP will attempt to use the very first Hardware Semaphore on the C6678.  If I understand you correctly, CSL is part of the PDK and essentially is automatically used so you cannot unuse it right?  If this is the case and CSL and GateMP are in contention for the same Hardware Semaphore, then you may need to configure GateMP to use a different Semaphore.  Are you able to determine if they are in contention for the same Hardware Semaphore?

    Judah

  • Hi Judah,

     

    Thank you for your reply.

     

    I use coreId as call argument to make it simple to illustrate the problem. But this does not seem to be case to you. So for your better understanding, I just changed to set the handler's argument to system interrupt number as below:

     

      CpIntc_mapSysIntToHostInt(m_intcId, m_sysInt, m_hostInt);

     

    And then modified the handler code as follows:

     

    extern "C" void EdmaCompletedTask(UArg arg)

    {

      int coreId = MultiProc_self();

      //if(coreId == (int) arg)

      {

        iFlags |= 1 << (arg - 8);

        CacheWbInv(&iFlags);

        gTraceQ->PostEdmaCompl();

      }

    }

     

    Here I know my system interrupt is in range of 8 to 11, so I just hardwired to minus 8 for updating variable iFlags which is initiliazed to 0. The result is the same as shown by the log below from the modified code.

     

    [C66xx_0] edmaId(1), m_intcId(0): m_sysInt(8) => m_hostInt(0)

    [C66xx_1] edmaId(1), m_intcId(0): m_sysInt(9) => m_hostInt(0)

    [C66xx_3] edmaId(1), m_intcId(0): m_sysInt(11) => m_hostInt(0)

    [C66xx_2] edmaId(1), m_intcId(0): m_sysInt(10) => m_hostInt(0)

    [C66xx_0] dstMsg(0082cb38), m_dspSeqNum(0), m_sysInt(8)

    [C66xx_0] CTraceQ::TraceEdmaCompleted() - 0 core0

    [C66xx_1] CTraceQ::TraceEdmaCompleted() - 0 core1

    [C66xx_2] CTraceQ::TraceEdmaCompleted() - 0 core2

    [C66xx_3] CTraceQ::TraceEdmaCompleted() - 0 core3

    [C66xx_0] 00000001

    [C66xx_1] 00000002

    [C66xx_2] 00000004

    [C66xx_3] 00000008

     

    1. That is, even if only core0 with system interrupt 8 issued an EDMA request, its completion also caused the interrupt handler got called on other cores with their own system interrupt number as argument. If the call had used core0's ystem interrupt number as argument, I would have been able to tell who's EDMA completion triggered the interrupt. Does using system interrupt help you understand my problem now?

     

    2. Regarding the earlier sysbios using C6670 event to host map for a project confiured for C6678, I know this bug has been fixed, and I am using the fixed version.

     

    3. When using CPIntc from sysbios with GateMP, I do not have the problem reported in that thread. I have not checked whether this is the same if I use CPIntc from CSL of the PDK, since I was advised not to use CpIntc from CSL.

     

    4. I have not found that I need to configure GateMP to use a particular hardware semaphore. But if I do in the future, how can I do this?

     

    Dongning

     

     

     

     

     

     

  • Dongning,

    Dongning Li said:
     

    1. That is, even if only core0 with system interrupt 8 issued an EDMA request, its completion also caused the interrupt handler got called on other cores with their own system interrupt number as argument. If the call had used core0's ystem interrupt number as argument, I would have been able to tell who's EDMA completion triggered the interrupt. Does using system interrupt help you understand my problem now?

    I don't having a understanding of EMDA so bare with me as I ask more EMDA questions:

    1.  So you are telling me that an EDMA completion will cause system interrupt 8, 9, 10, and 11 to all get triggered?  First question would be why does it trigger all those system interrupts and not just the one?   Is there anything in the EDMA itself that tells you which completion actually occured because it seems to me that you need extra logic in your ISR handler to check the status of EDMA?

    2.  You say "If the call had used core0's system interupt number as argument, I would have been able to tell who's EDMA completion triggered the interrupt".

    I don't understand this statement.  This is why I thought passing the system interrupt as the argument would give you this info.  What call are you talking about?

    Judah

  • Dear Judah,

     

    Thank you for your prompt reply.

    First regarding EDMA, each of the core0 to core3 is configured to uses its own EDMA channel. EDMA channels are configured to use regions 0 to 3, respectively for core0 to core3, to generate EDMA completion system interrupts. These interrupts have fixed number for INTC0 as specified by table 7-39 in C6678 data sheet (TMS320C6678 Multicore Fixed and Floating-Point Digital Signal Processor). Here these system interrupt numbers are 8 to 11. These system interrupts are all mapped to the same host interrupt 0. The host interrupt is further mapped to hardware interrupt 4.

    Here core0 is using system interrupt 8. When an EDMA request issued by core0 is completed, ideally only core0’s interrupt handler should be called, or if all other interrupt handlers using the same host interrupt get called, the same call argument as that for core0 should be used. In my example (after the code revision), the argument value should be the system interrupt number 8 used by core0. However, this is not the case. Core1, core 2 and core3’s interrupt handlers are all get called, and core1’s interrupt handler is called with argument 9, core2’s with 10 and core3’s with 11. When handling these interrupts, I do not know which system interrupt is actually caused the interrupt handler gets called.

    Now answer your two questions:

    1.       Core0’s EDMA completion causes system interrupt 8 gets triggered, which in turn triggers host interrupt 0. Since the system interrupts 9, 10 and 11 used respectively by core1, 2 and 3 are all mapped to the same host interrupt as that used by core0, this might be the reason that interrupt handler of core 1, 2, and 3 are also called. Please note that here by saying the handler gets called on core1 to core3 is not the same as system interrupts 9, 10 and 11 are all triggered. The problem here is that when the interrupt handler is called on core 1, 2 and 3, they are called with argument values 9, 10, and 11, respectively. That is (in my test code), call EdmaCompletedTask(9) for core1, EdmaCompletedTask(10) for core2, and EdmaCompletedTask(11) for core3. If they were called as EdmaCompletedTask(8) for all these 4 cores, then I would know it is the system interrupt 8 that happened. However, this is not the case and this is the reason I am seeking an answer/explanation from E2E forum.

    2.       Here I mean that if calling the interrupt handler EdmaCompletedTask (UArg arg) for core0, 1, 2 and 3 all uses the same argument value arg = 8, I would know that system interrupt 8 gets triggered. However, the test shows that interrupt handler is called on core1, 2 and 3 as well. In addition, they are called by using argument value arg = 9, 10, and 11 for core1, 2 and 3, respectively. Please note that in my test, no EDMA request is issued whose EDMA completion system interrupt is 9, 10, or 11.

    Why passing the system interrupt as the argument would give me this (log) info is also to my surprise. This unexpected result is exactly part of the reason of my original posting of this thread to get an answer and/or explanation.

     

    Dongning

  • Donging,

    I think I understand what you are saying but It looks to me like the real source of the problem is why does System Interrupt 8 completion caused Sys int 9, 10 , 11 to also be triggered?

    When the Isr handler on core 1, core 2, and core 3 are called, they are called with arguments 9, 10 , 11 respectively because that's how you have setup your CpIntc.  During your setup, you said, if sys int 9 is triggered, call it with argument 9, and 10 with 10, etc...  That's why the real question here is why is Sys Int 9, 10, and 11 being triggered?

    I think there's a couple of things you can experiment with:

    1.  You can try putting system interrupt 9, 10, 11 on different host interrupts.

    2.  If #1 doesn't work, you can try using different Hwi vector.

    Ultimately though you need to figure out why System Int 8 is causing System int 9, 10, 11 to be triggered because when CpIntc_dispatch processes a host_interrupt, it checks which system interrupt caused the interrupt and calls its function with argument.  If system int 9, 10 , 11 are not triggered, their handler would not be called.

    Judah

  • Hi Judah

    Thank you for your reply.

    Here I need to clarify a confusion.  As said in my yesterday’s posting, ISR handler getting called on core 1, 2 and 3 does not necessarily mean that system interrupts 9, 10 and 11 are triggered.  However, their associated host interrupt is indeed triggered since this host interrupt is also associated with system interrupt 8 and we know system interrupt 8 is triggered due to EDMA completion on core0.

    Regarding the experiments you suggested, I already did these in the past and know the results as described below:

    1.       Mapping each system interrupt to a different host interrupt without mapping each host interrupt to a unique HWI vector does not work. The code cannot be built.

    2.       Mapping each host interrupt to a unique HWI vector does not solve the problem as reported in my other E2E thread given below.

    http://e2e.ti.com/support/dsp/c6000_multi-core_dsps/f/639/p/139674/505987.aspx#505987

    In this thread I did not mention what argument value is passed when ISR handler is called. But if I configure the argument to use system interrupt just as the revised code did in this thread, I get the following log:

    [C66xx_0] edmaId(1), m_intcId(0): m_sysInt(8) => m_hostInt(32)

    [C66xx_1] edmaId(1), m_intcId(0): m_sysInt(9) => m_hostInt(44)

    [C66xx_2] edmaId(1), m_intcId(0): m_sysInt(10) => m_hostInt(56)

    [C66xx_3] edmaId(1), m_intcId(0): m_sysInt(11) => m_hostInt(68)

    [C66xx_0] dstMsg(0082cb38), m_dspSeqNum(0), m_sysInt(8)

    [C66xx_0] CTraceQ::TraceEdmaCompleted() - 0 core0

    [C66xx_1] CTraceQ::TraceEdmaCompleted() - 0 core1

    [C66xx_2] CTraceQ::TraceEdmaCompleted() - 0 core2

    [C66xx_3] CTraceQ::TraceEdmaCompleted() - 0 core3

    [C66xx_0] 00000001

    [C66xx_1] 00000002

    [C66xx_2] 00000004

    [C66xx_3] 00000008

     

    This is unexpected. Could you reproduce this problem?

     

    Dongning

  • Can you build your executable with "debug" profile and attach it here.  Also you are on 6670 correct?  Is there anything else that I would need to run your executable?

    Also make sure you do the following in your .cfg file: 

        var BIOS = xdc.useModule('ti.sysbios.BIOS');   

        BIOS.libType = BIOS.LibType_Debug;

    Judah

  • Hi Judal,

    Thank you for your reply.

    I attached the code for my test project which is for C6678.

    1321.TestTrace.zip

    The code runs on TMDXEVM6678L emulation board. 

    Dongning

     

  • Dongning,

    Okay, I took your example rebuilt it and did some experiments with it.  Here's what I found:

    1.  Static configuration DOES WORK however it might not do what's expected.  I basically commented the runtime calls of CpIntc and uncommented some of the config stuff in your *.cfg file.  Let me first state that you should stay with your dynamic runtime calls because of what you are doing.  Namely you want only sysInt 8 to core0, sysInt 9 to core1, etc...  However, I want to post this here to say that, static configuartion in your *.cfg does work.  I do get the interrupts on Hwi4 on core 0, but I also got Hwi6, Hwi7, and Hwi12 on core 0 because all those Hwi vectors are plugged with Host Interrupt 21.

            CpIntc.sysInts[8].fxn = '&EdmaCompletedTask';
            CpIntc.sysInts[8].arg = 8;             
            CpIntc.sysInts[8].hostInt = 32;        
            CpIntc.sysInts[8].enable = true;            

           CpIntc.sysInts[9].fxn = '&EdmaCompletedTask';
           CpIntc.sysInts[9].arg = 9;             
           CpIntc.sysInts[9].hostInt = 43;        
           CpIntc.sysInts[9].enable = true;            

           CpIntc.sysInts[10].fxn = '&EdmaCompletedTask';
           CpIntc.sysInts[10].arg = 10;             
           CpIntc.sysInts[10].hostInt = 54;        
           CpIntc.sysInts[10].enable = true;            

           CpIntc.sysInts[11].fxn = '&EdmaCompletedTask';
           CpIntc.sysInts[11].arg = 11;             
           CpIntc.sysInts[11].hostInt = 65;        
           CpIntc.sysInts[11].enable = true;            

            CpIntc.sysInts[24].fxn = '&EdmaCompletedTask';
            CpIntc.sysInts[24].arg = 24;              
            CpIntc.sysInts[24].hostInt = 32;         
            CpIntc.sysInts[24].enable = true;            

            CpIntc.sysInts[25].fxn = '&EdmaCompletedTask';
            CpIntc.sysInts[25].arg = 25;             
            CpIntc.sysInts[25].hostInt = 43;        
            CpIntc.sysInts[25].enable = true;            

            CpIntc.sysInts[26].fxn = '&EdmaCompletedTask';
            CpIntc.sysInts[26].arg = 26;             
            CpIntc.sysInts[26].hostInt = 54;        
            CpIntc.sysInts[26].enable = true;            

            CpIntc.sysInts[27].fxn = '&EdmaCompletedTask';
            CpIntc.sysInts[27].arg = 27;             
            CpIntc.sysInts[27].hostInt = 65;        
            CpIntc.sysInts[27].enable = true;            

            CpIntc.mapHostIntToHwiMeta(32 + 11*0, 4 + 0); /* core 0, host 32 map to hwi 4*/
            CpIntc.mapHostIntToHwiMeta(32 + 11*1, 4 + 8); /* core 1, host 43 map to hwi 12 */
            CpIntc.mapHostIntToHwiMeta(32 + 11*2, 4 + 2); /* core 2, host 54 map to hwi 6 */
            CpIntc.mapHostIntToHwiMeta(32 + 11*3, 4 + 3); /* core 3, host 65 map to hwi 7 */

    2.  I confirmed as I have suspected, which is SysInt 9, SysInt 10, and SysInt 11 are BEING triggered!  SysInt 8 is not the only one being triggered!  This makes sense because on core 1, The ISR would only be triggered if SysInt 9 was triggered.  For core 2 SysInt10 and for core 3 SysInt11.  How I determine this was looking at the CP_INTC registers below on core 0 when the ISR is taken.  The address I looked at is  0x02600200.  It  shows a value of 0xF40 on core 0 when I get to my ISR.  The "F" means that system interrupt 8, 9, 10, 11 were triggered.

    1.1     System Interrupt Status Raw/Set Registers (Base Address + 0x200 … 0x27C)

     

    The System Interrupt Status Raw/Set Registers show the pending enabled status of the system interrupts. Software can write to the Status Set Registers to set a system interrupt without a hardware trigger. There is one bit per system interrupt. If the number of system interrupts is greater than 32 then multiple registers are used for each 32 system interrupts.

     

    Bits

    Field

    Type

    Reset

    Description

    31:N

    reserved

    r/o

    0

    Always read as 0. Writes have no effect.

    N-1:0

    raw_status

    w/s

    0

    System interrupt raw status and setting.

    Reads return the raw status.

    Write a 1 in a bit position to set the status of the system interrupt. Writing a 0 has no effect.

    3.  Its best to keep all the CpIntc stuff in the *.cfg or *.c file and not have a mix in both.  It was very confusing trying to understand what you were trying to do in parts of the *.cfg file with respect to the CpIntc configuration.  I cleaned up the project so that the *.cfg DOES NOT do any CpIntc configuration and all of it is done within the TraceQ.cpp file.  After doing this, I plug Hwi Int 4 for all cores and I'm receing this interrupt 4 on all cores.  The next issue is that the GateMP_enter is failing.  I did not look into why its failing but it looks to me like You did not call GateMP_open() correctly for cores 1, 2, 3.  You need to do the GateMP_open in a while loop until its successful....Its just like doing any Ipc module open().  Please see how the Ipc examples do open for MessageQ and/or HeapBufMP.

    In conclusion:  You need to figure out why SysInt 9, 10, 11 are being triggered.  I assume this has to do with the EDMA configuration?  Then you need to correctly call GateMP_open() within a while loop.  After those two things, and with my modifications, I think things should work for.  I attached the modified proejct here.  I should note that I did build with a later SYSBIOS (6.32.04.49) and IPC (1.24.00.16) builds however that shouldn't matter for what you are doing.

    7245.UpdateTest.zip

    Judah 

     

  • Hi Judah,

     

    Thank you for your reply.

     

    1. I have not bothered to verify static configuration. There are many inconsistent test results which I need to concentrate on. I prefer to using dynamic configuration, and from your modified code, I now understand how to do it. 

     

    2. From raw status register, I can also see that other system interrupts are triggered. However, this does not solve my problem why they are triggered, which is an unexpected result to me. In fact, when checking EDMA IPR/IPRH, I do not see there are any other interrupts pending than the one associated with EDMA channel used by core0. Here core0, 1, 2, and 3 use respectively transfer completion code 8, 9, 10 and 11. IPRH/IPR pair has value 0x00000000 0x00000100 as shown by the log below:

    [C66xx_0] edmaId(1), m_intcId(0): m_sysInt(8) => m_hostInt(32)

    [C66xx_1] edmaId(1), m_intcId(0): m_sysInt(9) => m_hostInt(44)

    [C66xx_2] edmaId(1), m_intcId(0): m_sysInt(10) => m_hostInt(56)

    [C66xx_3] edmaId(1), m_intcId(0): m_sysInt(11) => m_hostInt(68)

    [C66xx_0] evt(21), host(32), hwi(4)

    [C66xx_1] evt(22), host(44), hwi(12)

    [C66xx_2] evt(23), host(56), hwi(6)

    [C66xx_3] evt(24), host(68), hwi(7)

    [C66xx_0] rawStatus(00000000), eventFlag(0000800d), enableReg(00000f00)

    [C66xx_0] dstMsg(0082d080), m_dspSeqNum(0), m_sysInt(8)

    [C66xx_0] CTraceQ::TraceEdmaCompleted() - 0 core0, IPR(00000000 00000100)

    [C66xx_1] rawStatus(00000000), eventFlag(0000000c), enableReg(00000f00)

    [C66xx_2] rawStatus(00000000), eventFlag(0000000c), enableReg(00000f00)

    [C66xx_3] rawStatus(00000000), eventFlag(0000000c), enableReg(00000f00)

    [C66xx_1] CTraceQ::TraceEdmaCompleted() - 0 core1, IPR(00000000 00000100)

    [C66xx_2] CTraceQ::TraceEdmaCompleted() - 0 core2, IPR(00000000 00000100)

    [C66xx_3] CTraceQ::TraceEdmaCompleted() - 0 core3, IPR(00000000 00000100)

    [C66xx_0] iFlags(00000001), hostIntFlags(00000001), rawStatus(00000f40), eventFlag(0020800d), enableReg(00000f00)

    [C66xx_2] iFlags(00000004), hostIntFlags(00000004), rawStatus(00000f40), eventFlag(0080000d), enableReg(00000f00)

    [C66xx_3] iFlags(00000008), hostIntFlags(00000008), rawStatus(00000f40), eventFlag(0100000d), enableReg(00000f00)

    [C66xx_1] iFlags(00000002), hostIntFlags(00000002), rawStatus(00000f40), eventFlag(0040000d), enableReg(00000f00)

    which is generated from my modified code attached in this posting. In my modified code, I use my own dispatch CpIntc_dispatch_(), which does not clear system interrupts to show what system interrupts have happened. Using my modified version of CpIntc_dispatch(), I am able to find which system interrupt is triggered. This actually answers the question I asked in my original posting. However, the tests also reveal other issue.

    Since each EDMA shadow region has a fixed system interrupt, so does the global interrupt, I just do not understand how one EDMA transfer completion could trigger 5 interrupts (4 shadow regions and one global). Is there any thing wrong about how I use EDMA?

     

    3. I mixed CpIntc stuff from both cfg and C code because sysbios's CpIntc does not have a C API for associating host interrupt with HWI. If you think that other developers could also get confused as I did, it is highly recommended to add a C API to do this association in CpIntc.

    I can see that your modified C code, different host interrupts are associate with the same hardware interrupt which runtime error. This is not possible if coded in cfg script. Doing this in cfg will cause a build failure. This inconsistent behavior should also be addressed. Furthermore, is the ussage correct to map different host interrupts to teh same hardware interrupt?

    I could not see what is wrong about how I use GateMP. I do call GateMP_open() in a loop in my original code for the cores which does not create GateMP:

        do {

          Task_sleep(1);

          rc = m_traceQueueLockable.Open("traceQueueL");

        } while(rc < 0);

    where object m_traceQueueLockable is a GateMP wrapper of type CGateMP defined in ScopedLock.h.

     

    I noticed your modified project has .cproject and .project files modified. Using these modified files I also have some problems with GateMP, but not if I use the unmodified versions of these files.

     

    In conclustions, I cannot figure out why sysInt 9, 10, and 11 are being triggered. This conflicts with the IPR/IPRH register values. The Edma channel is setup with

        CSL_EDMA3_ITCCH_DIS,

        CSL_EDMA3_TCCH_DIS,

        CSL_EDMA3_ITCINT_DIS,

    and no linking. How could one EDMA transfer completion cause 5 system interrupts? I could accept if there were two, one for shadow region, and one for the global. But even in this case, I am not sure whether it is correct to chip’s specification since I only use shadow region.

    If after reading my this posting, you still think the way how I use GateMP is wrong, please let me know why.

    I am not sure if the GateMP problem you encountered is due to the project files or the newer version of IPC build. GateMP is indeed packaged in IPC.

     

    Dongning 

     5126.TestTrace20111101.zip

  • Donging,

    This thread is getting way too long.  Its going to be hard for anybody else to follow this thread.  Especially because there are numerous issues being discussed.  I think there's at least 3 different things being discussed. #1. EDMA - why it triggers multiple system interrupts.  #2. CpIntc configuration. #3 GateMP.

    I don't have an answer for Issue #1.  I suggest, open up a new thread for #1 and ask the specific question about EDMA.  Also, open it up in the EVM6678 forum (if possible) and not BIOS forum because you need someone with more hardware specific knowledge to answer that question.

    Issue #2 and #3, I will try to answer here.

    For issue #2 concerining CpIntc configuration.  You have to realize that since you are building 1 executable for all cores, static configuration does not make a lot of sense here.  If you were building 4 executables, 1 per each core, then you could replicate your dynamic configuration in each your *.cfg file.  We don't associate a host interrupt with a Hwi because that is configurable and left up to the user to make that choice.  In the 'C' code it looks like I'm associating different Host interrupts with the same Hardware Interrupt but that's okay because it is running on different cores.  It would not be okay if it was on the same core.  In static config, you don't know which core you are running on and that's why you can't do the same thing.  Its not that they are "not consistent", its just the difference between dynamic (which you know which core you are on) versus static (you don't know which core you are on typically) configuration. 

    For issue #3 with GateMP, I didn't see your loop there in the project.  You definitely need to do the GateMP_open() in a loop.  There's a tool called ROV which could help you debug if you don't already know about it.  See:  http://rtsc.eclipse.org/docs-tip/Runtime_Object_Viewer for more information.   I don't know what ".cproject" and ".project" files are for.  They must be part of the CCS project?  I modified the project and probably these got modified along with that but I didn't actually edit this files themself.  If you are doing GateMP in a loop, you should probably be okay.

    Judah

  • Hi Judah,

    Thank you very much for your reply.

    For issue #1 I already have the following thread posted to C6000 Multicore DSP forum:


    http://e2e.ti.com/support/dsp/c6000_multi-core_dsps/f/639/p/139674/505987.aspx#505987


    But I have not heard any reply after 3 weeks. I will chase and discuss this issue in that thread.


    Your reply regarding issue #2 is very helpful for clarifying some of my confusions. Thank you again.

    For issue #3, the loop is in lines 527 to 530 of file TraceQ.cpp. As GateMP works for me when using my project files, I am not going to discuss it any more before I encounter it again.

    With your help, at least I have my original question of this posting answered, i.e., using my own version of CpIntc_dispatch(), where system interrupt triggered is known before it is cleared.

    I will discuss the issue #1 in that separate thread and will mark the question being answered when asked for verifying/rejecting the answer.

    Dongning