lkml.org 
[lkml]   [2010]   [Nov]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [PATCH v2 08/20] ARM: LPAE: MMU setup for the 3-level page table format
    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.
    >
    > Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
    > ---
    > arch/arm/kernel/head.S | 96 +++++++++++++++++++++++++++++++------------
    > arch/arm/mm/mmu.c | 32 ++++++++++++++-
    > arch/arm/mm/proc-macros.S | 5 +-
    > arch/arm/mm/proc-v7.S | 99 ++++++++++++++++++++++++++++++++++++++++----
    > 4 files changed, 193 insertions(+), 39 deletions(-)
    >
    > diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
    > index dd6b369..fd8a29e 100644
    > --- 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.

    > +#endif
    > +
    > .globl swapper_pg_dir
    > - .equ swapper_pg_dir, KERNEL_RAM_VADDR - 0x4000
    > + .equ swapper_pg_dir, KERNEL_RAM_VADDR - PG_DIR_SIZE
    >
    > .macro pgtbl, rd
    > - ldr \rd, =(KERNEL_RAM_PADDR - 0x4000)
    > + ldr \rd, =(KERNEL_RAM_PADDR - PG_DIR_SIZE)
    > .endm
    >
    > #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) ?


    \
     
     \ /
      Last update: 2010-11-22 14:13    [W:0.029 / U:0.172 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site