btauro
Posts: 30
Joined: Fri Jan 12, 2018 3:11 am

Synchronous Exception Synchronous exception: Data abort, same EL, Address size fault at level 1:

Wed Feb 07, 2018 5:54 am

Hi,
I have been trying to initialise circle 64 MMU but so far when i try creating the translation tables i get this

Code: Select all

Synchronous exception: Data abort, same EL, Address size fault at level 1:
ESR_EL1 00000025og96000061 ELR_EL1 00000000000003C4
 SPSR_EL1 0000000000083C18 FAR_EL1 0000000000083C20
 X30 000000000029FF60
 SpEl0 00000000002A8000
 Sp_EL1 000000000029FF94
Can anyone help me with this what could be the reason

bzt
Posts: 98
Joined: Sat Oct 14, 2017 9:57 pm

Re: Synchronous Exception Synchronous exception: Data abort, same EL, Address size fault at level 1:

Thu Feb 08, 2018 6:02 pm

Hi,

Generally decode ESR_EL1 register, it will tell you the exact cause and at which step the error occured during translation. See ARM DDI0487 chapter D10.2.28. For your problem, it is a bad paging table entry at level 1. Dump your tables, compare the entry with the documentation to see which bits are set up incorrectly. I assume either you set up wrong (or unaligned) memory address for the tables, therefore the entry is complete garbage, or you put a non-canonized physical address in the entry maybe? Anyway, dump your tables, find the entry used by your failing address to see what's going on.

Cheers,
bzt

btauro
Posts: 30
Joined: Fri Jan 12, 2018 3:11 am

Re: Synchronous Exception Synchronous exception: Data abort, same EL, Address size fault at level 1:

Sat Feb 10, 2018 8:00 pm

Thank you so much still looking into it but for some reason a parameter in level 3 table descriptor that is the ignored field if commented it works fine .I am not sure why.

Code: Select all

struct TARMV8MMU_LEVEL3_PAGE_DESCRIPTOR
{
        u64     Value11         : 2,            // set to 3
                //LowerAttributes       : 10,
                        AttrIndx        : 3,    // [2:0], see MAIR_EL1
                        NS              : 1,    // RES0, set to 0
                        AP              : 2,    // [2:1]
                        SH              : 2,    // [1:0]
                        AF              : 1,    // set to 1, will fault otherwise
                        nG              : 1,    // set to 0
                Reserved0_1     : 4,            // set to 0
                OutputAddress   : 32,           // [47:16]
                Reserved0_2     : 4,            // set to 0
                //UpperAttributes       : 12
                        Continous       : 1,    // set to 0
                        PXN             : 1,    // set to 0, 1 for device memory
                        UXN             : 1,    // set to 1
                        Ignored         : 9     // set to 0
                ;
}

Code: Select all

// pDesc->Ignored       = 0;

bzt
Posts: 98
Joined: Sat Oct 14, 2017 9:57 pm

Re: Synchronous Exception Synchronous exception: Data abort, same EL, Address size fault at level 1:

Fri Feb 16, 2018 7:59 pm

That's only the structure. I haven't checked it, I trust you can compare it to the spec. What's more important, you should dump the translation table entry to see what values those bitfields have. Something like:

Code: Select all

void dump_entry(struct struct TARMV8MMU_LEVEL3_PAGE_DESCRIPTOR *entry)
{
	printf("Entry at %lx: ", entry);
	printf(" Value11: %d", etnry->Value11);
	printf(" AttrIdx: %d", etnry->AttrIdx);
	printf(" AP: %d", etnry->AP);
	// ... und so weiter
}
And call it like:

Code: Select all

dump_entry((struct TARMV8MMU_LEVEL3_PAGE_DESCRIPTOR *)table[(vaddr>>T0SZ_LEVEL1)&LEVEL_MASK]);
Where 'table' is your paging table, 'T0SZ_LEVEL1' is the bitoffset of level1 in virtual address, and 'LEVEL_MASK' has as many 1s as one level in your configuration requires. (Sorry, I cannot be more specific, as ARM MMU is so flexible, there are so many ways to configure). To print out level2 entry, you should use the address in the level1 entry instead of 'table'.

I wouldn't call it a nice code 'cos I just put it together quickly, but here's a working example with 4k pageframe and 3 levels. There to get level 1's entry index I do '(addr>>(12+9+9))&0x1FF'. The function 'dbg_pagingflags(entry)' dumps the bitfields of a paging table entry, and 'dbg_paging(addr)' walks through the translation table and prints out every entry along the path for a virtual address in 'addr'.
a.png
a.png (853 Bytes) Viewed 566 times
In this example the table is at physical address 0x82000, and virtual address selects the first (0th) entry which has the physical address 0x83000, at level 1 the first entry again, at level 2 the last (511th) entry, and finally the in page offset is 4024.

It worth mentioning that you can only read virtual memory, but (naturally) entries hold physical addresses, so unless you have an identity mapping, you have to map the appropriate part of the translation table, that's what 'vmm_map()' calls are for.

Cheers,
bzt

Return to “Bare metal, Assembly language”

Who is online

Users browsing this forum: No registered users and 4 guests