[ARM] Set bit 4 on section mappings correctly depending on CPU
Russell King [Thu, 29 Jun 2006 17:24:21 +0000 (18:24 +0100)]
On some CPUs, bit 4 of section mappings means "update the
cache when written to".  On others, this bit is required to
be one, and others it's required to be zero.  Finally, on
ARMv6 and above, setting it turns on "no execute" and prevents
speculative prefetches.

With all these combinations, no one value fits all CPUs, so we
have to pick a value depending on the CPU type, and the area
we're mapping.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

20 files changed:
arch/arm/kernel/asm-offsets.c
arch/arm/kernel/head.S
arch/arm/mm/mm-armv.c
arch/arm/mm/proc-arm1020.S
arch/arm/mm/proc-arm1020e.S
arch/arm/mm/proc-arm1022.S
arch/arm/mm/proc-arm1026.S
arch/arm/mm/proc-arm6_7.S
arch/arm/mm/proc-arm720.S
arch/arm/mm/proc-arm920.S
arch/arm/mm/proc-arm922.S
arch/arm/mm/proc-arm925.S
arch/arm/mm/proc-arm926.S
arch/arm/mm/proc-sa110.S
arch/arm/mm/proc-sa1100.S
arch/arm/mm/proc-v6.S
arch/arm/mm/proc-xsc3.S
arch/arm/mm/proc-xscale.S
include/asm-arm/pgtable-hwdef.h
include/asm-arm/procinfo.h

index 447ede5..cc2d58d 100644 (file)
@@ -105,6 +105,7 @@ int main(void)
   BLANK();
   DEFINE(PROC_INFO_SZ,         sizeof(struct proc_info_list));
   DEFINE(PROCINFO_INITFUNC,    offsetof(struct proc_info_list, __cpu_flush));
-  DEFINE(PROCINFO_MMUFLAGS,    offsetof(struct proc_info_list, __cpu_mmu_flags));
+  DEFINE(PROCINFO_MM_MMUFLAGS, offsetof(struct proc_info_list, __cpu_mm_mmu_flags));
+  DEFINE(PROCINFO_IO_MMUFLAGS, offsetof(struct proc_info_list, __cpu_io_mmu_flags));
   return 0; 
 }
index 330b947..81cb902 100644 (file)
@@ -221,7 +221,7 @@ __create_page_tables:
        teq     r0, r6
        bne     1b
 
-       ldr     r7, [r10, #PROCINFO_MMUFLAGS]   @ mmuflags
+       ldr     r7, [r10, #PROCINFO_MM_MMUFLAGS] @ mm_mmuflags
 
        /*
         * Create identity mapping for first MB of kernel to
@@ -272,8 +272,7 @@ __create_page_tables:
 #endif
 
 #ifdef CONFIG_DEBUG_LL
-       bic     r7, r7, #0x0c                   @ turn off cacheable
-                                               @ and bufferable bits
+       ldr     r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags
        /*
         * Map in IO space for serial debugging.
         * This allows debug messages to be output
index 95273de..d06440c 100644 (file)
@@ -303,16 +303,16 @@ static struct mem_types mem_types[] __initdata = {
                .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
                                L_PTE_WRITE,
                .prot_l1   = PMD_TYPE_TABLE,
-               .prot_sect = PMD_TYPE_SECT | PMD_SECT_UNCACHED |
+               .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_UNCACHED |
                                PMD_SECT_AP_WRITE,
                .domain    = DOMAIN_IO,
        },
        [MT_CACHECLEAN] = {
-               .prot_sect = PMD_TYPE_SECT,
+               .prot_sect = PMD_TYPE_SECT | PMD_BIT4,
                .domain    = DOMAIN_KERNEL,
        },
        [MT_MINICLEAN] = {
-               .prot_sect = PMD_TYPE_SECT | PMD_SECT_MINICACHE,
+               .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_MINICACHE,
                .domain    = DOMAIN_KERNEL,
        },
        [MT_LOW_VECTORS] = {
@@ -328,25 +328,25 @@ static struct mem_types mem_types[] __initdata = {
                .domain    = DOMAIN_USER,
        },
        [MT_MEMORY] = {
-               .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
+               .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_AP_WRITE,
                .domain    = DOMAIN_KERNEL,
        },
        [MT_ROM] = {
-               .prot_sect = PMD_TYPE_SECT,
+               .prot_sect = PMD_TYPE_SECT | PMD_BIT4,
                .domain    = DOMAIN_KERNEL,
        },
        [MT_IXP2000_DEVICE] = { /* IXP2400 requires XCB=101 for on-chip I/O */
                .prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
                                L_PTE_WRITE,
                .prot_l1   = PMD_TYPE_TABLE,
-               .prot_sect = PMD_TYPE_SECT | PMD_SECT_UNCACHED |
+               .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_UNCACHED |
                                PMD_SECT_AP_WRITE | PMD_SECT_BUFFERABLE |
                                PMD_SECT_TEX(1),
                .domain    = DOMAIN_IO,
        },
        [MT_NONSHARED_DEVICE] = {
                .prot_l1   = PMD_TYPE_TABLE,
-               .prot_sect = PMD_TYPE_SECT | PMD_SECT_NONSHARED_DEV |
+               .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_NONSHARED_DEV |
                                PMD_SECT_AP_WRITE,
                .domain    = DOMAIN_IO,
        }
@@ -376,14 +376,21 @@ void __init build_mem_type_table(void)
                ecc_mask = 0;
        }
 
-       if (cpu_arch <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale()) {
-               for (i = 0; i < ARRAY_SIZE(mem_types); i++) {
+       /*
+        * Xscale must not have PMD bit 4 set for section mappings.
+        */
+       if (cpu_is_xscale())
+               for (i = 0; i < ARRAY_SIZE(mem_types); i++)
+                       mem_types[i].prot_sect &= ~PMD_BIT4;
+
+       /*
+        * ARMv5 and lower, excluding Xscale, bit 4 must be set for
+        * page tables.
+        */
+       if (cpu_arch < CPU_ARCH_ARMv6 && !cpu_is_xscale())
+               for (i = 0; i < ARRAY_SIZE(mem_types); i++)
                        if (mem_types[i].prot_l1)
                                mem_types[i].prot_l1 |= PMD_BIT4;
-                       if (mem_types[i].prot_sect)
-                               mem_types[i].prot_sect |= PMD_BIT4;
-               }
-       }
 
        cp = &cache_policies[cachepolicy];
        kern_pgprot = user_pgprot = cp->pte;
@@ -407,8 +414,8 @@ void __init build_mem_type_table(void)
                 * bit 4 becomes XN which we must clear for the
                 * kernel memory mapping.
                 */
-               mem_types[MT_MEMORY].prot_sect &= ~PMD_BIT4;
-               mem_types[MT_ROM].prot_sect &= ~PMD_BIT4;
+               mem_types[MT_MEMORY].prot_sect &= ~PMD_SECT_XN;
+               mem_types[MT_ROM].prot_sect &= ~PMD_SECT_XN;
 
                /*
                 * Mark cache clean areas and XIP ROM read only
index b9abbaf..efeebe7 100644 (file)
@@ -527,6 +527,9 @@ __arm1020_proc_info:
        .long   PMD_TYPE_SECT | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
+       .long   PMD_TYPE_SECT | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
        b       __arm1020_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
index 8c7e25f..78622ac 100644 (file)
@@ -492,6 +492,10 @@ __arm1020e_proc_info:
                PMD_BIT4 | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
+       .long   PMD_TYPE_SECT | \
+               PMD_BIT4 | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
        b       __arm1020e_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
index 92218e6..840dfc8 100644 (file)
@@ -475,6 +475,10 @@ __arm1022_proc_info:
                PMD_BIT4 | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
+       .long   PMD_TYPE_SECT | \
+               PMD_BIT4 | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
        b       __arm1022_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
index 2796c8e..72b75d9 100644 (file)
@@ -471,6 +471,10 @@ __arm1026_proc_info:
                PMD_BIT4 | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
+       .long   PMD_TYPE_SECT | \
+               PMD_BIT4 | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
        b       __arm1026_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
index 7a705ed..0432e48 100644 (file)
@@ -355,6 +355,10 @@ __arm6_proc_info:
                .long   0x41560600
                .long   0xfffffff0
                .long   0x00000c1e
+               .long   PMD_TYPE_SECT | \
+                       PMD_BIT4 | \
+                       PMD_SECT_AP_WRITE | \
+                       PMD_SECT_AP_READ
                b       __arm6_setup
                .long   cpu_arch_name
                .long   cpu_elf_name
@@ -371,6 +375,10 @@ __arm610_proc_info:
                .long   0x41560610
                .long   0xfffffff0
                .long   0x00000c1e
+               .long   PMD_TYPE_SECT | \
+                       PMD_BIT4 | \
+                       PMD_SECT_AP_WRITE | \
+                       PMD_SECT_AP_READ
                b       __arm6_setup
                .long   cpu_arch_name
                .long   cpu_elf_name
@@ -387,6 +395,10 @@ __arm7_proc_info:
                .long   0x41007000
                .long   0xffffff00
                .long   0x00000c1e
+               .long   PMD_TYPE_SECT | \
+                       PMD_BIT4 | \
+                       PMD_SECT_AP_WRITE | \
+                       PMD_SECT_AP_READ
                b       __arm7_setup
                .long   cpu_arch_name
                .long   cpu_elf_name
@@ -408,6 +420,10 @@ __arm710_proc_info:
                        PMD_BIT4 | \
                        PMD_SECT_AP_WRITE | \
                        PMD_SECT_AP_READ
+               .long   PMD_TYPE_SECT | \
+                       PMD_BIT4 | \
+                       PMD_SECT_AP_WRITE | \
+                       PMD_SECT_AP_READ
                b       __arm7_setup
                .long   cpu_arch_name
                .long   cpu_elf_name
index 8610246..fb4110a 100644 (file)
@@ -246,6 +246,10 @@ __arm710_proc_info:
                        PMD_BIT4 | \
                        PMD_SECT_AP_WRITE | \
                        PMD_SECT_AP_READ
+               .long   PMD_TYPE_SECT | \
+                       PMD_BIT4 | \
+                       PMD_SECT_AP_WRITE | \
+                       PMD_SECT_AP_READ
                b       __arm710_setup                          @ cpu_flush
                .long   cpu_arch_name                           @ arch_name
                .long   cpu_elf_name                            @ elf_name
@@ -267,6 +271,10 @@ __arm720_proc_info:
                        PMD_BIT4 | \
                        PMD_SECT_AP_WRITE | \
                        PMD_SECT_AP_READ
+               .long   PMD_TYPE_SECT | \
+                       PMD_BIT4 | \
+                       PMD_SECT_AP_WRITE | \
+                       PMD_SECT_AP_READ
                b       __arm720_setup                          @ cpu_flush
                .long   cpu_arch_name                           @ arch_name
                .long   cpu_elf_name                            @ elf_name
index 02af3e2..b9f1bd1 100644 (file)
@@ -461,6 +461,10 @@ __arm920_proc_info:
                PMD_BIT4 | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
+       .long   PMD_TYPE_SECT | \
+               PMD_BIT4 | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
        b       __arm920_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
index 33dae49..bda0aea 100644 (file)
@@ -465,6 +465,10 @@ __arm922_proc_info:
                PMD_BIT4 | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
+       .long   PMD_TYPE_SECT | \
+               PMD_BIT4 | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
        b       __arm922_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
index aaa9f98..a28da8f 100644 (file)
@@ -526,6 +526,10 @@ __arm925_proc_info:
                PMD_BIT4 | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
+       .long   PMD_TYPE_SECT | \
+               PMD_BIT4 | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
        b       __arm925_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
@@ -545,6 +549,10 @@ __arm915_proc_info:
                PMD_BIT4 | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
+       .long   PMD_TYPE_SECT | \
+               PMD_BIT4 | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
        b       __arm925_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
index ce246dd..496a233 100644 (file)
@@ -477,6 +477,10 @@ __arm926_proc_info:
                PMD_BIT4 | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
+       .long   PMD_TYPE_SECT | \
+               PMD_BIT4 | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
        b       __arm926_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
index 5a760a2..31a0908 100644 (file)
@@ -255,6 +255,9 @@ __sa110_proc_info:
                PMD_SECT_CACHEABLE | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
+       .long   PMD_TYPE_SECT | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
        b       __sa110_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
index 0a2107a..4e2489c 100644 (file)
@@ -276,6 +276,9 @@ __sa1100_proc_info:
                PMD_SECT_CACHEABLE | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
+       .long   PMD_TYPE_SECT | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
        b       __sa1100_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
@@ -296,6 +299,9 @@ __sa1110_proc_info:
                PMD_SECT_CACHEABLE | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
+       .long   PMD_TYPE_SECT | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
        b       __sa1100_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
index ca13d4d..ff77896 100644 (file)
@@ -269,6 +269,10 @@ __v6_proc_info:
                PMD_SECT_CACHEABLE | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
+       .long   PMD_TYPE_SECT | \
+               PMD_SECT_XN | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
        b       __v6_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
index 8d32e21..9aea506 100644 (file)
@@ -487,7 +487,14 @@ cpu_xsc3_name:
 __xsc3_proc_info:
        .long   0x69056000
        .long   0xffffe000
-       .long   0x00000c0e
+       .long   PMD_TYPE_SECT | \
+               PMD_SECT_BUFFERABLE | \
+               PMD_SECT_CACHEABLE | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
+       .long   PMD_TYPE_SECT | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
        b       __xsc3_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
index 29bcc4d..f4aeb7b 100644 (file)
@@ -595,6 +595,9 @@ __80200_proc_info:
                PMD_SECT_CACHEABLE | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
+       .long   PMD_TYPE_SECT | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
        b       __xscale_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
@@ -615,6 +618,9 @@ __8032x_proc_info:
                PMD_SECT_CACHEABLE | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
+       .long   PMD_TYPE_SECT | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
        b       __xscale_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
@@ -635,6 +641,9 @@ __8033x_proc_info:
                PMD_SECT_CACHEABLE | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
+       .long   PMD_TYPE_SECT | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
        b       __xscale_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
@@ -655,6 +664,9 @@ __pxa250_proc_info:
                PMD_SECT_CACHEABLE | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
+       .long   PMD_TYPE_SECT | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
        b       __xscale_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
@@ -675,6 +687,9 @@ __pxa210_proc_info:
                PMD_SECT_CACHEABLE | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
+       .long   PMD_TYPE_SECT | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
        b       __xscale_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
@@ -695,6 +710,9 @@ __ixp2400_proc_info:
                PMD_SECT_CACHEABLE | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
+       .long   PMD_TYPE_SECT | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
        b       __xscale_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
@@ -715,6 +733,9 @@ __ixp2800_proc_info:
                PMD_SECT_CACHEABLE | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
+       .long   PMD_TYPE_SECT | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
        b       __xscale_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
@@ -735,6 +756,9 @@ __ixp42x_proc_info:
                PMD_SECT_CACHEABLE | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
+       .long   PMD_TYPE_SECT | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
        b       __xscale_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
@@ -750,7 +774,14 @@ __ixp42x_proc_info:
 __ixp46x_proc_info:
        .long   0x69054200
        .long   0xffffff00
-       .long   0x00000c0e
+       .long   PMD_TYPE_SECT | \
+               PMD_SECT_BUFFERABLE | \
+               PMD_SECT_CACHEABLE | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
+       .long   PMD_TYPE_SECT | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
        b       __xscale_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
@@ -771,6 +802,9 @@ __pxa255_proc_info:
                PMD_SECT_CACHEABLE | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
+       .long   PMD_TYPE_SECT | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
        b       __xscale_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
@@ -791,6 +825,9 @@ __pxa270_proc_info:
                PMD_SECT_CACHEABLE | \
                PMD_SECT_AP_WRITE | \
                PMD_SECT_AP_READ
+       .long   PMD_TYPE_SECT | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
        b       __xscale_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
index 1bc1f99..f3b5120 100644 (file)
@@ -28,6 +28,7 @@
  */
 #define PMD_SECT_BUFFERABLE    (1 << 2)
 #define PMD_SECT_CACHEABLE     (1 << 3)
+#define PMD_SECT_XN            (1 << 4)        /* v6 */
 #define PMD_SECT_AP_WRITE      (1 << 10)
 #define PMD_SECT_AP_READ       (1 << 11)
 #define PMD_SECT_TEX(x)                ((x) << 12)     /* v5 */
index 8425260..edb7b65 100644 (file)
@@ -29,7 +29,8 @@ struct processor;
 struct proc_info_list {
        unsigned int            cpu_val;
        unsigned int            cpu_mask;
-       unsigned long           __cpu_mmu_flags;        /* used by head.S */
+       unsigned long           __cpu_mm_mmu_flags;     /* used by head.S */
+       unsigned long           __cpu_io_mmu_flags;     /* used by head.S */
        unsigned long           __cpu_flush;            /* used by head.S */
        const char              *arch_name;
        const char              *elf_name;