Post Go back to editing

How to Safely Share and Access L3 Memory Area Between Cores on ADSP-SC594

Category: Software
Product Number: ADSP-SC594

We are currently developing on the ADSP-SC594 and would like some advice regarding inter-core memory access. My development environment is as follows:

Environment:

  • Processor: ADSP-SC594
    • Core0: ARM Cortex-A5
    • Core1: SHARC
    • Core2: SHARC
  • IDE: CrossCore Embedded Studio 3.0.1.0
  • OS: FreeRTOS Version V10.5.1 on Core0 (installed via add-in)

Objective:

We would like to share the L3 memory region between the cores (ARM Core0 / SHARC Core1 / SHARC Core2) and access it safely without interference or conflicts.

Questions:

  1. What is the recommended method for accessing the L3 memory region safely between cores, and are there any important considerations or best practices?

  2. On the SHARC cores (Core1 / Core2), there are functions such as (load|store)_exclusive_(8|16|32|64).
    Is it possible to use these functions to achieve safe inter-core memory access (e.g., for mutual exclusion)?

  3. If these functions are not suitable, are there alternative recommended methods for safe memory sharing between cores?

  4. On the ARM core (Core0), is there an equivalent function or mechanism to the SHARC (load|store)_exclusive_(8|16|32|64) functions?

  5. If there is no equivalent on the ARM core, what would be the recommended way to safely share memory between ARM and SHARC cores?

Any advice or guidance would be greatly appreciated.

Thank you very much for your support.

  • Hi,

    Thank you for your inquiry. 

    Please find the attached project, which demonstrates how both ARM and SHARC cores can access shared L3 memory for read and write operations.

    By default, the L3 memory region is read-only for the SHARC core. Therefore, the ARM core's MMU must be configured accordingly.

    The MMU configuration is done based on the Abstract Page Table (APT) defined by symbol _adi_mmu_absPageTable. You can copy the default version of the APT and modify SHARC memory region used for the heap is being accessible by the ARM.

    This file can be copied from the below path:

    <installation path>CrossCore Embedded Studio x.x.x\ARM\arm-none-eabi\arm-none-eabi\lib\src\cortex-a5\crt\apt-sc594.c

    For example replace:
    { 0x80000000u, 0x9FFFFFFFu, SHARC_L3},

    With

    { 0x80000000u, 0x9FFFFFFFu, ADI_MMU_RW_UNCACHED},

    Please find attached basic project for SC594 which shows that ARM and SHARC can both read and write shared L3 memory. This follows the above advice (adding a modified abstract page table to the ARM project).

    A few notes on the example:

    - This is a very naive example. We don't recommend using hard-coded addresses to share data, as is done for clarity here.

    - The apt file in the ARM project is modified at line 116

    - The cache is turned off for the shared L3 memory on the SHARC core, using the adi_cache_set_range API

    - The example, when run, should print that the value at the L3 address is 2 on the SHARC0 core and value 3 on the SHARC1, then subsequently 3 on the ARM core. To see this, when creating your Debug Configuration, make sure that you remove the Automatic Breakpoint at "main" on Core 1 and Core2 (SHARC0 and SHARC1), so that the SHARC cores runs without stopping when enabled from the ARM.

    Also, we recommend to refer the below links, which might be helpful to you.
    https://ez.analog.com/dsp/software-and-development-tools/cces/f/q-a/111377/structure-in-memory-accessible-by-all-three-cores
    https://ez.analog.com/dsp/sharc-processors/adsp-sc5xxadsp-215xx/f/q-a/63893/multi-core-shared-memory

    Hope this helps.

    Regards,
    Santha kumari.V

    SC594_L3_SharedMemory.zip

  • Hi Santha kumari.V,

    Thank you very much for your kind support regarding our previous inquiry.
    We appreciate your continued assistance this time as well.
    Also, thank you for your prompt response and for providing the sample project.

    However, unfortunately, the response and sample project did not meet our expectations.
    The provided solution simply sets the shared L3 memory region as non-cacheable, and each core reads and writes to it accordingly.
    (Of course, we understand that read/write conflicts are avoided by introducing timing differences (delays).
    However, since other cores cannot know exactly when and where the L3 memory region is being accessed, this approach is impractical in reality.)

    What we would like to understand is how to implement mutual exclusion in the following cases:

    • How to exclude our core's read/write operations when other cores' is writing to the L3 memory region.
    • How to exclude our core's write operations when other cores' is reading the L3 memory region (reads are allowed).
    • How to exclude other cores' read/write operations when our core's is writing to the L3 memory region.
    • How to exclude other cores' write operations when our core's is reading the L3 memory region (reads are allowed).

    In other words, we are referring to the commonly known "readers-writer lock" mechanism.

    For SHARC cores, we understand that the following APIs are available:

    • load_exclusive_8()
    • load_exclusive_16()
    • load_exclusive_32()
    • load_exclusive_64()
    • store_exclusive_8()
    • store_exclusive_16()
    • store_exclusive_32()
    • store_exclusive_64()

    Is it possible to implement a readers-writer lock using these APIs?

    Also, since these APIs are apparently not available on ARM cores, are there alternative APIs on ARM cores that can be used instead?
    If it is not possible to implement readers-writer locks using these APIs, could you please advise us on other methods or best practices?

    Thank you very much for your kind support.

    Best regards,
    MrKK

    Readers–writer lock:
    en.wikipedia.org/.../Readers–writer_lock

  • Hi,

    As you aware, SHARC+ cores uses load_exclusive_N() and store_exclusive_N() builtin functions for exclusive access, where as ARM uses LDREX and STREX instructions to do exclusive load and store.

    The pairs of Load-Exclusive and Store-Exclusive instructions are:
    • the word instructions LDREX and STREX
    • the halfword instructions LDREXH and STREXH
    • the byte instructions LDREXB and STREXB.

    We recommend to refer the attached document for more details about Load and Store Register Exclusive(LDREX and STREX).

    Also, please refer the below Ezone link regrading implementation of LDREX and STREX in ARM core:
    https://ez.analog.com/dsp/sharc-processors/adsp-sc59x/f/q-a/591531/how-to-access-l3-memory-from-the-arm-core-without-passing-via-the-data-cache-on-the-adsp-sc594/555409

    Hope this helps.

    Regards,
    Santhakumari.V

    PDF

  • HI,

    We are currently generating a verification code and testing its functionality.
    We may be unable to respond for a while until the functionality check is complete.
    Please wait a little while.

    Best regards,
    MrKK

  • Hi,

    Sure. Thank you for the update!!!

    Best Regards,

    Santhakumari.V

  • Hi,

    We created test code to verify functionality and confirmed its operation.
    While most operations performed as expected, we observed unexpected behavior in one specific case.
    Below are patterns that exhibit the expected behavior and patterns that do not exhibit the expected behavior.

    Expected behavior patterns

    Step Core Operation Result Behavior
    1 ARM Core 0 Load Success Expected
    2 SHARC Core 1 Load Success Expected
    3 ARM Core 0 Store Success Expected
    4 SHARC Core 1 Store Failure Expected
    Step Core Operation Result Behavior
    1 ARM Core 0 Load Success Expected
    2 SHARC Core 2 Load Success Expected
    3 ARM Core 0 Store Success Expected
    4 SHARC Core 2 Store Failure Expected
    Step Core Operation Result Behavior
    1 SHARC Core 1 Load Success Expected
    2 SHARC Core 2 Load Success Expected
    3 SHARC Core 1 Store Success Expected
    4 SHARC Core 2 Store Failure Expected
    Step Core Operation Result Behavior
    1 SHARC Core 2 Load Success Expected
    2 SHARC Core 1 Load Success Expected
    3 SHARC Core 2 Store Success Expected
    4 SHARC Core 1 Store Failure Expected

    Unexpected behavior patterns

    Step Core Operation Result Behavior
    1 SHARC Core 1 Load Success Expected
    2 ARM Core 0 Load Success Expected
    3 SHARC Core 1 Store Success Expected
    4 ARM Core 0 Store Success Unexpected
    Step Core Operation Result Behavior
    1 SHARC Core 2 Load Success Expected
    2 ARM Core 0 Load Success Expected
    3 SHARC Core 2 Store Success Expected
    4 ARM Core 0 Store Success Unexpected

     After SHARC Core 1 or 2 stores data, the ARM core overwrites it.

    The test code used for verification is also attached below:
    L3Mem_Exclu_Access_Example.zip

    Please feel free to point out any errors in how we use our API or assembler instructions.

    Best regards,
    MrKK

    P.S.
    The following warning occurs:


    [Warning li2131] app_Core1.ldf:1645 Input section(s) of incompatible init qualifier detected in the output section 'dxe_l3_shared_memory'


    We would appreciate it if you could point out any errors in our writing of section blocks.

  • Hi,

    Could you please explain your test code like how you are generating test patterns for both passed and failed cases.

    Regarding li2131,

    The linker warns you this if:

    •The section qualifier is not compatible with an initialization qualifier on an input section.
    •A section qualifier is on the output section and an input section without a qualifier is mapped into it.
    •No section qualifier is on the output section and an input section with a qualifier is mapped into it.

    You can check the Linker Log xml file, as mentioned in the warning text. This will be cause by a mismatch in the init qualifier for a section - e.g. data is marked in the source as "NO_INIT", but is being placed in an output section that explicitly calls for "ZERO_INIT", for example.

    For more details, please refer the below mentioned CCES help path:
    CrossCore® Embedded Studio 3.x.x > SHARC® Development Tools Documentation > Linker and Utilities Manual > Linker and Archiver Messages > Linker Messages > Warnings > li2131

    Waiting for your reply.

    Best Regards,
    Santhakumari.V

  • Hi,

    We will explain the test pattern.

    int main(int argc, char *argv[])
    {
    	...
    
    	while (true)
    	{
            ...
    
    		for (volatile uint32_t wait_cnt = 0x01000000UL; wait_cnt > 0UL; wait_cnt--);    <- [1]
    
    		do
    		{
    			is_locked = ShrdMem_Lock(SHRDMEM_WRITE_ID);
    			if (!is_locked)
    			{
    				Dbg_Core2_Exclusive_Count++;
    			}
    		} while (!is_locked);
    
    		...
    	}
    
    	return 0;
    }
    
    ...
    
    bool ShrdMem_Lock(const shrdmem_rw_id rw_id)
    {
    	...
    
    	while (true)
    	{
    		lock1.u8_val = ShrdMem_ExclusiveLoad8(lock_addr, &is_exclu);                    <- [2]
    		if (is_exclu)                                                                   <- [3]
    		{
    			if (lock1.stat.mtx == SHRDMEM_MUTEX_UNLOCKED)
    			{
    				lock1.stat.mtx = SHRDMEM_MUTEX_LOCKED;
    
    				ShrdMem_ExclusiveStore8(lock_addr, lock1.u8_val, &is_exclu);            <- [4]
    				if (is_exclu)                                                           <- [5]
    				{
    					break;
    				}
    			}
    		}
    
        ...
    }

    Step1:
    Run all cores up to point marked [1].

    Step2:
    Run two of the cores (Core A, Core B) up to the point marked [2].

    Step3:
    Run only Core A up to the point marked [3] and Check a result. (* This step is step1 in the table.)

    Step4:
    Run only Core B up to the point marked [3] and Check a result. (* This step is step2 in the table.)

    Step5:
    Run two of the cores (Core A, Core B) up to the point marked [4].

    Step6:
    Run only Core A up to the point marked [5] and Check a result. (* This step is step3 in the table.)

    Step7:
    Run only Core B up to the point marked [5] and Check a result. (* This step is step4 in the table.)

    Please assign ARM Core 0, SHARC Core 1, and SHARC Core 2 to Core A and Core B as appropriate for each test case.
    Also, utilize menus such as [Run]->[Run to Line], [Run]->[Step Over] and [Run]->[Step Into] for run.

    Best regards,
    MrKK

  • Hi MrKK,

    Thank you for the detailed explanation.

    We have reproduced the observation you reported here. We are looking into it now.

    We will get back to you soon.

    Best Regards,
    Santha kumari.V

  • Dear Santha Kumari.V,

    Thank you very much for your prompt response and for reproducing the issue.
    We appreciate your efforts in investigating this matter.
    We will await your update and look forward to hearing from you soon.

    Best regards,
    MrKK