We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi,
I want to produce an exception in Foundation Model to test my ARMV8 U-boot. But when I set AF bit to 0 in last level page table entry, and want to produce an Access Flag exception, it failed, the same happened to Address size fault and Translation fault. But when I set AP bit(access ) , the permission fault can be reported to exception handler which I added to start.S.
I'm wondering if the Hardware page table walk in Foundation model can not report exception in handling page table entry? Cause permission fault is produced in TLB not in hardware page table walk.
Can anybody help me? Thanks very much in advance.
Hi heron, thanks for showing the interest in the Foundation model. Do you mind post a few key code segments please? For examples, how you set AF in the page table entry, the code that should trigger fault etc. Thanks, George
Thanks for your reply.
Here is my code to set up level 2 page table(I want to use 2M page size , so the last page table level is level 2).I just want to trigger Access Flag miss mentioned in the ARMV8 manual.
void set_level2_entries(unsigned long tlb_addr)
{
u64 *page_table = (u64 *)(tlb_addr + 0x2000);
u64 value;
//AF | NS | AP |Inner Shareable | block|AP
u64 flag = (1 << 10) | (1 << 5) | (3 << 8) | 0x1| ( 1 << 6 );
u64 flag1 = (1 << 5) | (3 << 8) | 0x1| ( 1 << 6 );
u32 i;
//Entry 0
/* UART 0x0 1C09 0000 ~ 0x0 1C09 0003*/
value = 0x1c000000;
value |= flag;
value |= (MT_DEVICE_nGnRnE << 2);
page_table[(0x1c0 >> 1)] = value;
/* GIC 0x0 2C00 1000 ~ 0x0 2C00 3FFF */
value = 0x2c000000;
value |= flag1;
page_table[(0x2c0 >> 1)] = value;
//Entry 1
page_table = (u64 *)(tlb_addr + 0x3000);
/* Device RAM 0x4000 0000 ~ 0x40FF FFFF */
for (i = 0; i < 8; i++) {
value = 0x40000000;
value |= (i << 21);
page_table[i] = value;
}
//Entry 2
page_table = (u64 *)(tlb_addr + 0x4000);
/* RAM 0x0 8000 0000 ~ 0x0 9FFF FFFF */
for (i = 0; i < 256; i++) {
value = 0x80000000;
value |= (MT_NORMAL << 2);
In other place of my project, I inserted some codes and want to trigger Access Flag, codes as follow:
asm("ldr x0, =0x2c001000");
asm("mov w1, #1");
asm("str w1,[x0]");
Looking forward to your reply. Thanks a lot.
Just be paranoid, did you enable the MMU?
Hi heron, sorry for the late reply. We have been trying to reproduce the problem you are mentioning, but unable to reproduce it. We have internal test program to test this behaviour, and from the tarmac trace, we can see the Access Flag is behaving as expected.
9 clk IT (9) 00000024 d2a58000 O EL3h_s : MOV x0,#0x2c000000
9 clk R X0 000000002C000000
10 clk IT (10) 00000028 b940001f O EL3h_s : LDR wzr,[x0,#0]
10 clk TTW DTLB LPAE 1:0 0000001000 0000000000002003 : TABLE PXN=0 XN=0 AP=0 NS=0 ADDR=0x0000000000002000
10 clk TTW DTLB LPAE 1:1 0000002000 0000000000004003 : TABLE PXN=0 XN=0 AP=0 NS=0 ADDR=0x0000000000004000
10 clk TTW DTLB LPAE 1:2 0000004b00 006000002c000041 : BLOCK ATTRIDX=0 NS=0 AP=1 SH=0 AF=0 nG=0 16E=0 PXN=1 XN=1 ADDR=0x000000002c000000
10 clk MR4 2c000000 00000000 (ABORTED)
10 clk E 00000028:0000000028 00000084 CoreEvent_CURRENT_SPx_SYNC
10 clk R cpsr 000003cd
10 clk R ESR_EL3 9600000a
10 clk R SPSR_EL3 000003cd
10 clk R FAR_EL3 000000002c000000
10 clk R ELR_EL3 0000000000000028
11 clk IT (11) 00000200 00000000 O EL3h_s : DCI 0x00000000 ; ? Undefined
We can see the descriptor is set up with AF=0, then in ESR_EL3, we see Access Flag fault is generated. It is suggesting the configuration code in your program might be incorrect, though we are not able to spot anything obviously wrong in the code you posted. So I think you need to enable tarmac trace to double check your pagetable configurations.
The command line to enable the tarmac trace is Foundation_v8pkg/models/Linux64_GCC-4.1/Foundation_v8 --image=test.axf --trace=/proc/self/fd/1
Thanks,
George