MMU issue on MQX4.1 for Vybrid

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MMU issue on MQX4.1 for Vybrid

363 Views
daweiyou
NXP Employee
NXP Employee

Hi team:

My customer found one MMU issue on MQX for vybrid, PLS check and confirm.

When they use Ethernet and SDHC driver together, for example FTP application, after running long period, they found SDHC card have 32bytes error data.

After disable L2 cache, the issue couldn't be reproduced.

they trace the code find that cache operation will call address translate function, _mmu_vtop, like below:

void _l2c310_cache_invalidate_line(void *addr)

{

    /* addr parameter can be virtual address and this cache work only with physical address */

    void   *pa = NULL; /* physical address pointer */

    if (_mmu_vtop(addr, &pa) == MQX_OK)

    {

        CA5L2C_reg7_inv_pa = (uint32_t)pa & (L2C_reg7_clean_pa_Index_MASK | L2C_reg7_clean_pa_Tag_MASK);

        /* Drain the STB. Operation complete when all buffers, LRB, LFB, STB, and EB, are emptyDrain the STB. Operation complete when all buffers, LRB, LFB, STB, and EB, are empty */

        while (CA5L2C_reg7_cache_sync & L2C_reg7_cache_sync_C_MASK);

    }

}

But this function _mmu_vtop do not prevent code reentry, the result will bring wrong PA address, which maybe write data to wrong address.

So whether need to add prevention code, like     _mmu_lock(); to avoid this potential issue?

/*!

* \brief translate virtual address to physical address

*

* \param va

* \param pa

*

* \return MQX_OK or an error code

*/

_mqx_int _mmu_vtop(void *va, void  **pa)

{

    /* VA to PA translation with privileged read permission check  */

    MCR(15, 0, (uint32_t)va & 0xfffffc00, 7, 8, 0);

    /* Read PA register */

    MRC(15, 0, *(uint32_t*)pa, 7, 4, 0);

    /* First bit of returned value is Result of conversion(0 is successful translation) */

    if ((uint32_t)*pa & 0x01)

    {

        /* We can try write permission also */

        /* VA to PA translation with privileged write permission check  */

        MCR(15, 0, (uint32_t)va & 0xfffffc00, 7, 8, 1);

        /* Read PA register */

        MRC(15, 0, *(uint32_t*)pa, 7, 4, 0);

        /* First bit of returned value is Result of conversion(0 is successful translation) */

        if ((uint32_t)*pa & 0x01)

        {

            return MQX_INVALID_POINTER;

        }

    }

    /* complete address returning base + offset*/

    *pa = (void *) (((uint32_t)*pa & 0xfffff000) | ((uint32_t)va & 0x00000fff));

    return MQX_OK;

}

0 Kudos
1 Reply

246 Views
alejandrolozan1
NXP Employee
NXP Employee

Hi,

After looking at your  description it makes sense. But before contacting the experts I wonder if you can share some simple example we can use to reproduce the problem.

Best Regards,

Alejandro

0 Kudos