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.

Non-cachable data section on MSMCSRAM

Hello,

 

I have two questions regarding data section in C6678 EVM.

1)

I mapped 0x0c000000 to virtual address 0xa0000000, and set the corresponding MAR bit to 0 in order to make whole MSMCSRAM non-cachable.

It is working fine if I read/write via virtual address (i.e, cache disabled).

What I want to do is defining data sections on non-cachable MSMCSRAM.

For example,

In .cfg file,

Program.sectMap[".Test"] = new Program.SectionSpec();
Program.sectMap[".Test"].loadAddress = 0xA0090000;

and in .c file,

#pragma SET_DATA_SECTION(".Test")

int a;

int b;

...

But, the compiler shows warning message as below.

I guess it is why the virtual address is too far.

warning: Section ".Test" requires a STATIC_BASE relative relocation, but is
   located at 0xa0090000, which is probably out of range of the STATIC_BASE.
   STATIC_BASE is located at 0x0081b400. Might be required to correct
   placement of ".Test" so it lies within 0x8000 of the STATIC_BASE.

 

Alternatively, I can define data sections on physical address of MSMCSRAM,

and make the c codes access via virtual address.

But, there are so many variables and structures on serveral data sections, so it is not appropriate to my case.

Or, if it is declared as 'far', can this problem be solved?

If so, where should I insert 'far' keyword and is there any performance difference between w/ far and w/o far?

Can anybody suggest the best solution?

 

2) Can I set the length of data section?

For example, I want to set the length of ".Test" section to 0x100,

so ".sharedMemory" below is not allocated between 0x0C000000 and 0x0C0000FF.

I can declare an array in ".Test" section like 'char Temp[0x100]'.

But, In case that the section size is too big (e.g.,3MB), it is not simple to declare 3MB array.

And, I want to make some data sections dedicated to predefined cores,

so I don't want to allocate array on the data sections which other cores are using.

Possible solutions are to use loadAddress only (not use loadSegment), or to define data segment instead of data section.

Is there a better solution?

Program.sectMap[".Test"] = new Program.SectionSpec();
Program.sectMap[".Test"].loadAddress = 0x0C000000;

Program.sectMap[".sharedMemory"] = new Program.SectionSpec();
Program.sectMap[".sharedMemory"].loadSegment = "MSMCSRAM";

  • Hi H Lee,

    Regarding the STATIC_BASE warning, the following thread is helpful.

    And if you want to disable cache for MSMCSRAM, 0x0c000000 is not appropriate.  MAR does not work at the address range.  You need to define a virtual address to access MSMCSRAM.

    > 2) Can I set the length of data section?

    My recommendation is to define some memory segments by RTSC Platform.  We can define different platforms for different cores.  The following site is based on CCS v4 but still helpful.

    Best Regards,
    Atsushi

  • Hi,

    H Lee said:

    Or, if it is declared as 'far', can this problem be solved?

    If so, where should I insert 'far' keyword and is there any performance difference between w/ far and w/o far?

    The far keyword should resolve the problem. About the syntax and overhead, look at compiler manual para.6.5.4 The Near and far keywords (SPRU187T). You can also compile all the code (or the part that reference those varaibles) with the option --mem_model:data=far.

    Reference (declaration in a .h, for a compilation unit that use the variables): extern far int a;

    Definition:  far int a;

    The overhead for a single access (to load the address of the variable) is of  1LDW instruction for the near case against 3 instruction for the far case. This is only for the first access: if you compile optimized the compiler will try to cache that address and reuse it in the next accesses so the real overhead could became inappreciable (that depend on your code).

    In my code I prefer to compile everithings with mem_model = far.

  • Thank you for answers.

    But, defining data section on virtual address is not clear yet.

    Suppose that physical address 0x0c000000 is mapped to 0xa0000000 using MPAX, and cache is disabled using MAR.

    One of my question was that below lines are valid or not.

    Program.sectMap[".Test"] = new Program.SectionSpec();
    Program.sectMap[".Test"].loadAddress = 0xA0000000;   // virtual address

    In c code, #pragma SET_DATA_SECTION(".Test") is added, and a lot of variables are declared below the above line.

    I expect all variables are non-cachable.

    But, because MPAX and MAR setting is done runtime (coded in main function),

    I'm not sure whether the variables are loaded properly and are set non-cachable.

    Compiler shows warning message because 0xA0000000 is out of range of DDR3.

    Can I define data sections on virtual address and does this approach have no problem?

    If not, what is the solution?

  • Hi H Lee,

    First, may I ask to explain the reason why you need to disable cache on MSMCSRAM?  Depending on the reason, we will be able to provide much better solution.

    Following, I assume you need to disable cache in anyway.

    I have checked the current SYS/BIOS manual.  I'm afraid but I did not find MPAX support in it.  So I will try to explain a way which doesn't depend on BIOS for MPAX.  (Some experts may have better suggestion.)

    A solution I have is as following.

    1. Prior to jump _c_int00 (C language start-up routine), configure MPAX.
    2. Jump to _c_int00.
    3. Before calling main(), the start-up routine automatically initializes global variable if they have initial values.
    4. In main(), write-back and invalidates any cache to secure the initial values.  (According to BIOS reference manual, BIOS Cache_setMar() API automatically write-back and invalidates cache.)
    5. Configure MAR by some way to disable cache.  (We can use BIOS for this purpose.)
    6. Call BIOS_start() at an appropriate point.

    By the way,

    > Compiler shows warning message because 0xA0000000 is out of range of DDR3.

    I recommend to use RTSC Platform which I have explained in the previous post and specify the segment name instead of an absolute address in .cfg.  By this, linker can recognize the memory segment and the warning may be disappeared.  (Consideration about .far is sill required.)

    Best Regards,
    Atsushi

  • Hi,

    You mean that variables may not be loaded properly with the approach I mentioned earlier.

    So, it is necessary to set virtual address before loading variables. Is it right?

    Can you help me implement your solution?

    - To configure MPAX before jumping to _c_int00, where should I put MPAX configuration code?

    - Is it right just to call Cache_setMar(0x0c000000,0x00400000,Cache_Mar_DISABLE) for step 4 and 5?

     

    I'm working on porting the already implemented multi-core application with non-cachable memory to TI DSP.

    Because the application includes lots of DMA copy operations and code size is too huge,

    it is difficult, maybe impossible considering time deadline, to add cache invalidate/write-back in all source codes and verify them.

     

     

     

  • Hi H Lee,

    > So, it is necessary to set virtual address before loading variables. Is it right?

    My understanding is yes.

    > - To configure MPAX before jumping to _c_int00, where should I put MPAX configuration code?

    In general, we need to conform the section 5.3.2 Run-Time Initialization and 7.8 System Initialization of SPRU187U, but in the case, we need to initialize stack pointer (SP) and data page pointer (DP).  It usually requires assembly language programing.

    If you use SYS/BIOS, a better and easier solution is using a hook function which BIOS provides.  Please refer the section 3.1 SYS/BIOS Startup Sequence of SPRUEX3L.  The document says we can use xdc.runtime.Reset but I found xdc.runtime.Startup might be better.

    Exactly speaking, we can configure the hook function by BIOS .cfg file as following.

    var Startup = xdc.useModule('xdc.runtime.Startup');
    Startup.resetFxn = "&reset_mpax";

    By this, before jumping into main(), BIOS initializer calls reset_mpax() in this example.  In the C source, we can write the following core for example.

    int global_a = 123;

    void reset_mpax(void)
    {
        // We can configure MPAX registers here.
        asm(" nop");
    }

    void main(void)
    {
        volatile int a;

        asm(" nop");
        a = global_a;
    }

    To observe registers initialization, my recommendation is put breakpoints on two asm(" nop") lines.

    In the case, you will see the global_a is not initialized when executing reset_mpax() but it has the intended initial value 123 when reached the main().  The fact is, when loading a code to memory, CCS automatically run the code until main(), so we explicitly need to assign _c_int00 into PC (program counter) after loading the code.  To realize this, we can open core registers window, find the PC register, click the original value and input _c_int00 in the value box.  The symbol _c_int00 will be replaced by the actual address of the symbol.

    When PC is set to _c_int00 and run the code, we see reset_mpax() is executed first (at this moment, global_a is not initialized yet), and it finally reaches main() and global_a is initialized.  In this manner, we can configure MPAX before initializing the variables.

    > - Is it right just to call Cache_setMar(0x0c000000,0x00400000,Cache_Mar_DISABLE) for step 4 and 5?

    Yes, I think it works.  For details, please refer the section 4.4.5 Memory Attribute Register (MARn) Definition of SPRUGW0B.

    > it is difficult, maybe impossible considering time deadline, to add cache invalidate/write-back in all source codes and verify them.

    Accessing cache-disabled memory (especially DDR memory) is often very slow.  In the case, please consider manual cache write-back and invalidation.

    Best Regards,
    Atsushi

  • The problem was solved.

    Thank you very much.