ELCHILEN0
Posts: 2
Joined: Sat Jan 27, 2018 8:17 am

Pi3 Device Memory

Wed Jan 31, 2018 8:59 pm

When configuring the MMU and the L1 TLB, I understand that the choice of memory for the peripheral address range should be one of:

Code: Select all

@ 31                 20 19  18  17  16 15  14   12 11 10  9  8     5   4    3 2   1 0
@ |section base address| 0  0  |nG| S |AP2|  TEX  |  AP | P | Domain | XN | C B | 1 0|
    L1_STRONGLY_ORDERED =      	 (0b000 << 12) | (0 << 3) | (0 << 2),
    L1_DEVICE_SHARE =          	 (0b000 << 12) | (0 << 3) | (1 << 2),
    L1_DEVICE_NO_SHARE =       	 (0b010 << 12) | (0 << 3) | (0 << 2),
I have setup a linear mapping using with addresses before the peripherals being mapped as

Code: Select all

    L1_NORMAL_001_11 = 0x00001c0e,	// outer and inner write-back, write-allocate 
and addresses 0x3F000000 onwards being mapped as one of the three variants above. The MMU enables correctly and the mapping behaves as expected; however, writes to the peripherals seem to be internally buffered or perhaps gathered instead of being device non-gathering. I have tried configuring Primary Region Remap Register (PRRR) - TR1 to 0b00 specify that the device memory should be nGnRnE as well as including explicit barriers after my writes to the peripherals but the buffering behavior has not changed.

My code to enable the MMU is as follows:

Code: Select all

// http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0344k/Bahfeedc.html
    uint32_t control;
    asm volatile("MRC p15, 0, %0, c1, c0, 0" : "=r" (control));
    control &= ~(1 << 0);   // Clear M to disable MMU
    control &= ~(1 << 2);   // Clear C to disable D Cache
    control &= ~(1 << 12);  // Clear I to disable I Cache
    control &= ~(1 << 11);  // Clear Z to disable branch prediction
    asm volatile("mcr p15, 0, %0, c1, c0, 0" :: "r" (control));
    
    // Flush L1 Cache, TLB, Branch Prediction
    asm("MCR p15, 0, %0, c7, c5, 0" :: "r" (0));
    asm("MCR p15, 0, %0, c7, c5, 6" :: "r" (0));
    asm("MCR p15, 0, %0, c8, c7, 0" :: "r" (0));
    // asm("ISB");

    unsigned auxctrl;
    asm volatile ("mrc p15, 0, %0, c1, c0,  1" : "=r" (auxctrl));
    printf("ax = 0x%X\r\n", auxctrl);
    auxctrl |= (1 << 6);
    asm volatile ("mcr p15, 0, %0, c1, c0,  1" :: "r" (auxctrl));

    asm volatile ("mcr p15, 0, %0, c2, c0, 2" :: "r" (0)); // TTBR0
    // http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0360f/CHDGIJFB.html
    asm volatile ("mcr p15, 0, %0, c2, c0, 0" :: "r" ((uint32_t) l1_page_table) : "memory");
    asm volatile ("mcr p15, 0, %0, c3, c0, 0" :: "r" (~0)); // DACR (allow everyone)
    asm volatile("isb");

    asm volatile("MRC p15, 0, %0, c1, C0, 0" : "=r" (control));
    printf("CTRL: 0x%X\r\n", control);
    control |= (1 << 0);    // Set M to enable MMU
    control |= (1 << 2);    // Set C to enable D Cache
    control |= (1 << 12);   // Set I to enable I Cache
    control |= (1 << 11);   // Set Z to enable branch prediction
    asm volatile("MCR p15, 0, %0, C1, C0, 0" :: "r" (control));
    asm volatile("isb");

ELCHILEN0
Posts: 2
Joined: Sat Jan 27, 2018 8:17 am

Re: Pi3 Device Memory

Fri Feb 02, 2018 12:49 am

Solved, the behavior I was seeing was due to the performance speedup when enabling the caching. With the instruction locality, the instructions were executed much quicker than my TTY buffer could read them causing "chunks" of data to be read at a time. When setting a GPIO pin to LOW would nearly immediately be followed by pin HIGH causing the led to appear as if it never turned off.

Return to “Bare metal, Assembly language”

Who is online

Users browsing this forum: No registered users and 3 guests