summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/include/asm/pgtable.h4
-rw-r--r--arch/arm/mm/proc-xsc3.S30
-rw-r--r--arch/arm/mm/proc-xscale.S52
3 files changed, 55 insertions, 31 deletions
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index 8df2e254a3e..8f039a08b00 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 ad1ce5a8922..96e47fc7fd6 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 8d7512f9cba..6fa525364bb 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