[PATCH v2 08/20] ARM: LPAE: MMU setup for the 3-level page table format

Catalin Marinas catalin.marinas at arm.com
Tue Nov 23 06:38:15 EST 2010


On 22 November 2010 13:10, Russell King - ARM Linux
<linux at arm.linux.org.uk> wrote:
> On Fri, Nov 12, 2010 at 06:00:28PM +0000, Catalin Marinas wrote:
>> This patch adds the MMU initialisation for the LPAE page table format.
>> The swapper_pg_dir size with LPAE is 5 rather than 4 pages. The
>> __v7_setup function configures the TTBRx split based on the PAGE_OFFSET
>> and sets the corresponding TTB control and MAIRx bits (similar to
>> PRRR/NMRR for TEX remapping). The 36-bit mappings (supersections) and
>> a few other memory types in mmu.c are conditionally compiled.
[...]
>> --- a/arch/arm/kernel/head.S
>> +++ b/arch/arm/kernel/head.S
>> @@ -21,6 +21,7 @@
>>  #include <asm/memory.h>
>>  #include <asm/thread_info.h>
>>  #include <asm/system.h>
>> +#include <asm/pgtable.h>
>>
>>  #ifdef CONFIG_DEBUG_LL
>>  #include <mach/debug-macro.S>
>> @@ -45,11 +46,20 @@
>>  #error KERNEL_RAM_VADDR must start at 0xXXXX8000
>>  #endif
>>
>> +#ifdef CONFIG_ARM_LPAE
>> +     /* LPAE requires an additional page for the PGD */
>> +#define PG_DIR_SIZE  0x5000
>> +#define PTE_WORDS    3
>> +#else
>> +#define PG_DIR_SIZE  0x4000
>> +#define PTE_WORDS    2
>
> PTE is not the right prefix here - we don't deal with the lowest level
> of page tables, which in Linux is called PTE.  I think you mean PMD_WORDS
> instead.

It should actually be something PMD_ORDER because of the log2 value.

>>  #ifdef CONFIG_XIP_KERNEL
>> @@ -129,11 +139,11 @@ __create_page_tables:
>>       pgtbl   r4                              @ page table address
>>
>>       /*
>> -      * Clear the 16K level 1 swapper page table
>> +      * Clear the swapper page table
>>        */
>>       mov     r0, r4
>>       mov     r3, #0
>> -     add     r6, r0, #0x4000
>> +     add     r6, r0, #PG_DIR_SIZE
>>  1:   str     r3, [r0], #4
>>       str     r3, [r0], #4
>>       str     r3, [r0], #4
>> @@ -141,6 +151,23 @@ __create_page_tables:
>>       teq     r0, r6
>>       bne     1b
>>
>> +#ifdef CONFIG_ARM_LPAE
>> +     /*
>> +      * Build the PGD table (first level) to point to the PMD table. A PGD
>> +      * entry is 64-bit wide and the top 32 bits are 0.
>> +      */
>> +     mov     r0, r4
>> +     add     r3, r4, #0x1000                 @ first PMD table address
>> +     orr     r3, r3, #3                      @ PGD block type
>> +     mov     r6, #4                          @ PTRS_PER_PGD
>> +1:   str     r3, [r0], #8                    @ set PGD entry
>> +     add     r3, r3, #0x1000                 @ next PMD table
>> +     subs    r6, r6, #1
>> +     bne     1b
>> +
>> +     add     r4, r4, #0x1000                 @ point to the PMD tables
>> +#endif
>> +
>>       ldr     r7, [r10, #PROCINFO_MM_MMUFLAGS] @ mm_mmuflags
>>
>>       /*
>> @@ -152,30 +179,30 @@ __create_page_tables:
>>       sub     r0, r0, r3                      @ virt->phys offset
>>       add     r5, r5, r0                      @ phys __enable_mmu
>>       add     r6, r6, r0                      @ phys __enable_mmu_end
>> -     mov     r5, r5, lsr #20
>> -     mov     r6, r6, lsr #20
>> +     mov     r5, r5, lsr #SECTION_SHIFT
>> +     mov     r6, r6, lsr #SECTION_SHIFT
>>
>> -1:   orr     r3, r7, r5, lsl #20             @ flags + kernel base
>> -     str     r3, [r4, r5, lsl #2]            @ identity mapping
>> -     teq     r5, r6
>> -     addne   r5, r5, #1                      @ next section
>> -     bne     1b
>> +1:   orr     r3, r7, r5, lsl #SECTION_SHIFT  @ flags + kernel base
>> +     str     r3, [r4, r5, lsl #PTE_WORDS]    @ identity mapping
>> +     cmp     r5, r6
>> +     addlo   r5, r5, #SECTION_SHIFT >> 20    @ next section
>> +     blo     1b
>>
>>       /*
>>        * Now setup the pagetables for our kernel direct
>>        * mapped region.
>>        */
>>       mov     r3, pc
>> -     mov     r3, r3, lsr #20
>> -     orr     r3, r7, r3, lsl #20
>> +     mov     r3, r3, lsr #SECTION_SHIFT
>> +     orr     r3, r7, r3, lsl #SECTION_SHIFT
>>       add     r0, r4,  #(KERNEL_START & 0xff000000) >> 18
>> -     str     r3, [r0, #(KERNEL_START & 0x00f00000) >> 18]!
>> +     str     r3, [r0, #(KERNEL_START & 0x00e00000) >> 18]!
>>       ldr     r6, =(KERNEL_END - 1)
>> -     add     r0, r0, #4
>> +     add     r0, r0, #1 << PTE_WORDS
>>       add     r6, r4, r6, lsr #18
>
> Are you sure these shifts by 18 places are correct?  They're actually
> (val >> SECTION_SHIFT) << 2, so maybe they should be (SECTION_SHIFT -
> PMD_WORDS) ?

SECTION_SHIFT - PMD_ORDER is (20 - 2) for classic page tables and (21
- 3) for LPAE. But we could change the 18 to some macros for
clarification (the line would be long though).

-- 
Catalin



More information about the linux-arm-kernel mailing list