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

From: Catalin Marinas
Date: Tue Nov 23 2010 - 06:38:21 EST


On 22 November 2010 13:10, Russell King - ARM Linux
<linux@xxxxxxxxxxxxxxxx> 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
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/