diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/include/asm/pgtable.h | 4 | ||||
-rw-r--r-- | arch/arm/mm/proc-xsc3.S | 30 | ||||
-rw-r--r-- | arch/arm/mm/proc-xscale.S | 52 |
3 files changed, 55 insertions, 31 deletions
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index 8df2e254a3e4..8f039a08b00c 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h @@ -188,8 +188,8 @@ extern void __pgd_error(const char *file, int line, unsigned long val); #define L_PTE_MT_DEV_SHARED2 (0x05 << 2) /* 0101 (v6) */ #define L_PTE_MT_DEV_NONSHARED (0x0c << 2) /* 1100 */ #define L_PTE_MT_DEV_IXP2000 (0x0d << 2) /* 1101 */ -#define L_PTE_MT_DEV_WC (0x09 << 2) /* 1001 (pre-v6, !xsc3) */ -#define L_PTE_MT_DEV_WC2 (0x08 << 2) /* 1000 (xsc3, v6) */ +#define L_PTE_MT_DEV_WC (0x09 << 2) /* 1001 (pre-v6) */ +#define L_PTE_MT_DEV_WC2 (0x08 << 2) /* 1000 (v6) */ #define L_PTE_MT_DEV_CACHED (0x0b << 2) /* 1011 */ #define L_PTE_MT_MASK (0x0f << 2) diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S index ad1ce5a89221..96e47fc7fd6f 100644 --- a/arch/arm/mm/proc-xsc3.S +++ b/arch/arm/mm/proc-xsc3.S @@ -347,16 +347,36 @@ ENTRY(cpu_xsc3_switch_mm) * Set a PTE and flush it out * */ + +cpu_xsc3_mt_table: + .long 0x00 @ L_PTE_MT_UNCACHED + .long PTE_BUFFERABLE @ L_PTE_MT_BUFFERABLE + .long PTE_EXT_TEX(5) | PTE_CACHEABLE @ L_PTE_MT_WRITETHROUGH + .long PTE_EXT_TEX(5) | PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_WRITEBACK + .long 0x00 @ L_PTE_MT_DEV_SHARED + .long 0x00 @ L_PTE_MT_DEV_SHARED2 + .long 0x00 @ L_PTE_MT_MINICACHE (not present) + .long PTE_EXT_TEX(5) | PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_WRITEALLOC (not present?) + .long PTE_EXT_TEX(1) @ L_PTE_MT_DEV_WC2 + .long PTE_EXT_TEX(1) @ L_PTE_MT_DEV_WC + .long 0x00 @ unused + .long PTE_EXT_TEX(5) | PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_DEV_CACHED + .long 0x00 @ L_PTE_MT_DEV_NONSHARED + .long 0x00 @ L_PTE_MT_DEV_IXP2000 (not present) + .long 0x00 @ unused + .long 0x00 @ unused + .align 5 ENTRY(cpu_xsc3_set_pte_ext) xscale_set_pte_ext_prologue - @ If it's cacheable, it needs to be in L2 also. - tst r1, #L_PTE_CACHEABLE - orrne r2, r2, #PTE_EXT_TEX(0x5) - tst r1, #L_PTE_SHARED @ shared? - orrne r2, r2, #0x200 + and r1, r1, #L_PTE_MT_MASK + adr ip, cpu_xsc3_mt_table + ldr ip, [ip, r1] + orrne r2, r2, #PTE_EXT_COHERENT @ interlock: mask in coherent bit + bic r2, r2, #0x0c @ clear old C,B bits + orr r2, r2, ip xscale_set_pte_ext_epilogue mov pc, lr diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S index 8d7512f9cba7..6fa525364bb7 100644 --- a/arch/arm/mm/proc-xscale.S +++ b/arch/arm/mm/proc-xscale.S @@ -406,8 +406,6 @@ ENTRY(cpu_xscale_dcache_clean_area) /* =============================== PageTable ============================== */ -#define PTE_CACHE_WRITE_ALLOCATE 0 - /* * cpu_xscale_switch_mm(pgd) * @@ -431,34 +429,40 @@ ENTRY(cpu_xscale_switch_mm) * * Errata 40: must set memory to write-through for user read-only pages. */ +cpu_xscale_mt_table: + .long 0x00 @ L_PTE_MT_UNCACHED + .long PTE_BUFFERABLE @ L_PTE_MT_BUFFERABLE + .long PTE_CACHEABLE @ L_PTE_MT_WRITETHROUGH + .long PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_WRITEBACK + .long 0x00 @ L_PTE_MT_DEV_SHARED + .long 0x00 @ L_PTE_MT_DEV_SHARED2 + .long PTE_EXT_TEX(1) | PTE_CACHEABLE @ L_PTE_MT_MINICACHE + .long PTE_EXT_TEX(1) | PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_WRITEALLOC + .long PTE_BUFFERABLE @ L_PTE_MT_DEV_WC2 + .long PTE_BUFFERABLE @ L_PTE_MT_DEV_WC + .long 0x00 @ unused + .long PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_DEV_CACHED + .long 0x00 @ L_PTE_MT_DEV_NONSHARED + .long PTE_EXT_TEX(1) | PTE_BUFFERABLE @ L_PTE_MT_DEV_IXP2000 + .long 0x00 @ unused + .long 0x00 @ unused + .align 5 ENTRY(cpu_xscale_set_pte_ext) xscale_set_pte_ext_prologue - @ - @ Handle the X bit. We want to set this bit for the minicache - @ (U = E = B = W = 0, C = 1) or when write allocate is enabled, - @ and we have a writeable, cacheable region. If we ignore the - @ U and E bits, we can allow user space to use the minicache as - @ well. - @ - @ X = (C & ~W & ~B) | (C & W & B & write_allocate) - @ - and ip, r1, #L_PTE_CACHEABLE | L_PTE_WRITE | L_PTE_BUFFERABLE - teq ip, #L_PTE_CACHEABLE -#if PTE_CACHE_WRITE_ALLOCATE - teqne ip, #L_PTE_CACHEABLE | L_PTE_WRITE | L_PTE_BUFFERABLE -#endif - orreq r2, r2, #PTE_EXT_TEX(1) @ - @ Erratum 40: The B bit must be cleared for a user read-only - @ cacheable page. - @ - @ B = B & ~(U & C & ~W) + @ Erratum 40: must set memory to write-through for user read-only pages @ - and ip, r1, #L_PTE_USER | L_PTE_WRITE | L_PTE_CACHEABLE - teq ip, #L_PTE_USER | L_PTE_CACHEABLE - biceq r2, r2, #PTE_BUFFERABLE + and ip, r1, #(L_PTE_MT_MASK | L_PTE_USER | L_PTE_WRITE) & ~(4 << 2) + teq ip, #L_PTE_MT_WRITEBACK | L_PTE_USER + + moveq r1, #L_PTE_MT_WRITETHROUGH + and r1, r1, #L_PTE_MT_MASK + adr ip, cpu_xscale_mt_table + ldr ip, [ip, r1] + bic r2, r2, #0x0c + orr r2, r2, ip xscale_set_pte_ext_epilogue mov pc, lr |