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.

Linux/AM5718: GateMP shared memory issue

Part Number: AM5718

Tool/software: Linux

Dear team,

I run the GateMP example for long time.The example protect share memory using the GateMP between A15 and DSP,but sometime it can not protect.

I follow the linux code GateHWSpinlock.c.

In  GateHWSpinlock_start

---------------------------------------------------------------------

    /* Fall back to /dev/mem if hwspinlock_user driver is not supported */
    Mod->fd = open("/dev/hwspinlock", O_RDWR);
    if (Mod->fd < 0) {
        Mod->fd = open ("/dev/mem", O_RDWR | O_SYNC);
    }
    else {
        Mod->useHwlockDrv = true;
    }
-----------------------------------------------------------------

The /dev dictionary does not have spinclock device, use /dev/mem?

I see page 5421 of the spruhz7f.pdf.  It said "A spinlock should only be held with interrupts disabled."

But in function GateHWSpinlock_enter

---------------------------------------------------------------

IArg GateHWSpinlock_enter(GateHWSpinlock_Object *obj)
{
    volatile UInt32 *baseAddr = Mod->baseAddr;
    struct hwspinlock_user_lock data = {
        .id = obj->lockNum,
        .timeout = 10,
    };
    IArg key;
    Bool locked;

    key = IGateProvider_enter(obj->localGate);

    /* if gate already entered, just return with current key */
    obj->nested++;
    if (obj->nested > 1) {
        return(key);
    }

    /* enter the spinlock */
    while (1) {
        if (Mod->useHwlockDrv) {
            locked = !ioctl(Mod->fd, HWSPINLOCK_USER_LOCK, &data);
        }
        else {
            /* read the spinlock, returns non-zero when we get it */
            locked = (baseAddr[obj->lockNum] == 0);
        }

        if (locked) {
            break;
        }

        obj->nested--;
        IGateProvider_leave(obj->localGate, key);
        key = IGateProvider_enter(obj->localGate);
        obj->nested++; /* re-nest the gate */
    }

    return (key);
}


---------------------------------------------------------------

The function IGateProvider_enter use the pthread_mutex_lock.

I am not find the operation to  disable  interrupt.

Does the code really make sure the hwspinlock work properly?

Here is my error log.

--> main:
CMEM_init success
--> Main_main:
--> GateMPApp_create:
GateMPApp_create: Host is ready
<-- GateMPApp_create:
--> GateMPApp_exec:
GateMPApp_exec: Using host-created gate
GateMPApp_exec: Using slave-created gate
GateMPApp_exec: unexpected variable value.Test failed.
GateMPApp_exec: Previous value: 518, c[ 3647.514352] omap_hwmod: mmu1_dsp1: _wait_target_disable failed
urrent value=1
<-- GateMPApp_exec: -268435456
<-- Main_main:
[ 3647.527235] omap_hwmod: mmu0_dsp1: _wait_target_disable failed
<-- main:

  • The software team have been notified. They will respond here.
  • Hi, Fei Liang,

    Linux user space can't disable interrupt. Since the test is single threaded, mutex is used to be sure no other thread is interrupting it.

    When you mention you run the GateMP test for long time, do you mean you repeatedly run the test? From the error log and code analysis, it seems that the memory got stepped on. Do you have other application running at the same time?

    Rex
  • Thanks for reply.

    This is my script.I think only one process running.

    --------------------------------------------------------------------------
    root@am57xx-evm:~# cat test.sh
    #!/bin/bash

    killall ti-mctd
    while true
    do
    ./reload_dsp_firmware.sh
    sleep 1
    rmmod cmemk.ko
    insmod cmemk.ko
    ./GateMPApp.host
    done
    ------------------------------------------------------------------------------

    If I move the loop into GateMPApp.host , it can work .

    like this:


    ------------------------------------------------------------------------------

    main_host.c

    Int Main_main(Void)
    {
        Int         status = 0;

        printf("--> Main_main:\n");

        /* BEGIN application phase */

        /* application create phase */
        status = GateMPApp_create();

        if (status < 0) {
            goto leave;
        }
    while(1){
        /* application execute phase */
        status = GateMPApp_exec();

        if (status < 0) {
            goto leave;
        }
    }
    ------------------------------------------------------------------------------

    DSP firmware

    -------------------------------------------------------------------------------

    gatempapp.c

    Void smain(UArg arg0, UArg arg1)
    {
        Int                 status = 0;

        Log_print0(Diags_ENTRY | Diags_INFO, "--> smain:");

        /* initialize modules */
        Server_init();

        /* turn on Diags_INFO trace */
        Diags_setMask("Server+F");

        /* server setup phase */
        status = Server_create();

        if (status < 0) {
            goto leave;
        }
        while(1){
        /* server execute phase */
        status = Server_exec();

        if (status < 0) {
            goto leave;
        }
        }

    -----------------------------------------------------------------------------

    very strange

  • Fei Liang,

    How do you reload the DSP firmware, using unbind/bind command? Could you show it as well?

    Rex