This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Read memory block loaded by bootloader at EL3, but on EL2

Hi Everyone,

I'm developing a bare-metal application to run on an ARM Cortex A53 core. 

I'm using u-boot compiled with the respective flags to start the application at EL3, so that we have full control of the processor configuration.

Right now, I'm trying to read a memory block of 181 bytes at address 0x8028000 while on EL2 but, most of the times, the processor is reading what looks like a memory block with some corrupted bytes.

The EL3 registers are configured as follows:

TCR_EL3 - 0x80823518

MAIR_EL3 - 0x000000ff440c0400

SCTLR_EL3 - 0x00C5183D

the L0 table (at address 0x8000c000):

0x8000c000:     0x000000008000d003      0x0000000000000000
0x8000c010:     0x0000000000000000      0x0000000000000000

the L1 table

0x8000d000:     0x000000008000e003      0x000000008000f003
0x8000d010:     0x0000000080000611      0x00000000c0000611
0x8000d020:     0x0000000000000000      0x0000000000000000

As I understand, address 0x80280000 would match index 0 and index 2 of table L0 and L1 respectively, which will lead to a block descriptor that configures the access to the 1GB block.

Also, analyzing the NS bit of the Table (bit 63) and Block (bit 5)  descriptors, we can see that those accesses are being translated into secure IPA or PA space.

I've tried to configure both descriptors to have the NS bit enabled and configured the EL2 MMU to access the block I wanted, but failed to read it without corruption.

Does anyone have a suggestion as to what I might be missing?

Thanks in advance.

Kind Regards,

pcarmo

Parents
  • Yeah, I agree with you, but even with the same attributes in both EL3 and EL2 I get this same issue.

    I am invalidating the TLB before enabling the MMU at EL2.

    At EL3, the bootloader (u-boot) sets up the EL3 tables and enables the MMU before handing off to my bare-metal application.

    In this case, I just configure the sections I want as non-secure and invalidate the TLBI, without disabling and enabling the MMU.

    I do this because I have tested to configure the MMU tables with MMU disabled at EL3, and the MMU configuration is lost as soon as I enable the MMU at EL3.

    In all situations, I invalidate the TLBs using the sequence suggested by the documentation:

        dsb ishst
        tlbi alle3is
        dsb ish
        isb

    In any case, I found a work around to this situation:

    I've changed the EL3 MMU table from

    0x8000d000:     0x000000008000e003      0x000000008000f003
    0x8000d010:     0x0000000080000611      0x00000000c0000611
    0x8000d020:     0x0000000000000000      0x0000000000000000

    to:

    0x8000d000:     0x000000008000e003      0x000000008000f003
    0x8000d010:     0x0000000080000611      0x0000000080000631
    0x8000d020:     0x0000000000000000      0x0000000000000000

    This way, at EL3:

    1. the block with virtual address 0x80000000 is pointing to the physical secure address 0x80000000

    2. the block with virtual address 0xC0000000 is pointing to the physical non-secure address 0x80000000

    At this point, I just copy the memory block starting at v_address 0x80000000 to the memory block starting at v_address 0xC0000000.

    As soon as I enable the MMU at EL2 with the MMU tables configured to allow access to the v_address 0x80000000, I am able to properly read the memory I want, without any incoherence.

    I am not sure if this is how it should be done, but it works fine and the copy loop runs quite fast, we don't even see a difference in the loading time, even though we are copying a 1GB memory block.

    Would appreciate any other suggestion, if there's a simpler approach.

    In any case, thanks for the help.

Reply
  • Yeah, I agree with you, but even with the same attributes in both EL3 and EL2 I get this same issue.

    I am invalidating the TLB before enabling the MMU at EL2.

    At EL3, the bootloader (u-boot) sets up the EL3 tables and enables the MMU before handing off to my bare-metal application.

    In this case, I just configure the sections I want as non-secure and invalidate the TLBI, without disabling and enabling the MMU.

    I do this because I have tested to configure the MMU tables with MMU disabled at EL3, and the MMU configuration is lost as soon as I enable the MMU at EL3.

    In all situations, I invalidate the TLBs using the sequence suggested by the documentation:

        dsb ishst
        tlbi alle3is
        dsb ish
        isb

    In any case, I found a work around to this situation:

    I've changed the EL3 MMU table from

    0x8000d000:     0x000000008000e003      0x000000008000f003
    0x8000d010:     0x0000000080000611      0x00000000c0000611
    0x8000d020:     0x0000000000000000      0x0000000000000000

    to:

    0x8000d000:     0x000000008000e003      0x000000008000f003
    0x8000d010:     0x0000000080000611      0x0000000080000631
    0x8000d020:     0x0000000000000000      0x0000000000000000

    This way, at EL3:

    1. the block with virtual address 0x80000000 is pointing to the physical secure address 0x80000000

    2. the block with virtual address 0xC0000000 is pointing to the physical non-secure address 0x80000000

    At this point, I just copy the memory block starting at v_address 0x80000000 to the memory block starting at v_address 0xC0000000.

    As soon as I enable the MMU at EL2 with the MMU tables configured to allow access to the v_address 0x80000000, I am able to properly read the memory I want, without any incoherence.

    I am not sure if this is how it should be done, but it works fine and the copy loop runs quite fast, we don't even see a difference in the loading time, even though we are copying a 1GB memory block.

    Would appreciate any other suggestion, if there's a simpler approach.

    In any case, thanks for the help.

Children
No data