summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Medhurst <tixy@linaro.org>2012-04-04 10:30:14 +0100
committerJon Medhurst <tixy@linaro.org>2012-04-04 10:30:14 +0100
commite3d227636d5988338bd49960fbc2956a6d49844d (patch)
tree0a3bdcc939deae865c875415edd84c43adfec296
parentf19a88fbaca0e9ea7dbd648a3eb153ffcdca452f (diff)
parent19b45d92a9bd07de334ba2ccdc6060aa5495cd07 (diff)
downloadvexpress-a9-e3d227636d5988338bd49960fbc2956a6d49844d.tar.gz
Merge branch 'tracking-armlt-arm-arch-fixes' into integration-android-vexpress
-rw-r--r--arch/arm/kernel/traps.c2
-rw-r--r--arch/arm/mm/cache-l2x0.c13
-rw-r--r--arch/arm/mm/context.c51
-rw-r--r--arch/arm/mm/proc-v7-2level.S10
4 files changed, 45 insertions, 31 deletions
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 504b28ac161..bcb8419728f 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -821,6 +821,6 @@ void __init early_trap_init(void)
memcpy((void *)(vectors + KERN_RESTART_CODE - CONFIG_VECTORS_BASE),
syscall_restart_code, sizeof(syscall_restart_code));
- flush_icache_range(vectors, vectors + PAGE_SIZE);
+ flush_icache_range(CONFIG_VECTORS_BASE, CONFIG_VECTORS_BASE+PAGE_SIZE);
modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
}
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index a6a84ffd39d..3b36f20c7b1 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -361,9 +361,6 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
l2x0_cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID);
aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
- aux &= aux_mask;
- aux |= aux_val;
-
/* Determine the number of ways */
switch (l2x0_cache_id & L2X0_CACHE_ID_PART_MASK) {
case L2X0_CACHE_ID_PART_L310:
@@ -372,6 +369,13 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
else
l2x0_ways = 8;
type = "L310";
+
+ /*
+ * Set bit 22 in the auxiliary control register. If this bit
+ * is cleared, PL310 treats Normal Shared Non-cacheable
+ * accesses as Cacheable no-allocate.
+ */
+ aux_val |= 1 << 22;
break;
case L2X0_CACHE_ID_PART_L210:
l2x0_ways = (aux >> 13) & 0xf;
@@ -403,6 +407,9 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
/* Make sure that I&D is not locked down when starting */
l2x0_unlock(l2x0_cache_id);
+ aux &= aux_mask;
+ aux |= aux_val;
+
/* l2x0 controller is disabled */
writel_relaxed(aux, l2x0_base + L2X0_AUX_CTRL);
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
index ee9bb363d60..efa413ad3bc 100644
--- a/arch/arm/mm/context.c
+++ b/arch/arm/mm/context.c
@@ -23,25 +23,37 @@ DEFINE_PER_CPU(struct mm_struct *, current_mm);
#endif
#ifdef CONFIG_ARM_LPAE
-#define cpu_set_asid(asid) { \
- unsigned long ttbl, ttbh; \
- asm volatile( \
- " mrrc p15, 0, %0, %1, c2 @ read TTBR0\n" \
- " mov %1, %2, lsl #(48 - 32) @ set ASID\n" \
- " mcrr p15, 0, %0, %1, c2 @ set TTBR0\n" \
- : "=&r" (ttbl), "=&r" (ttbh) \
- : "r" (asid & ~ASID_MASK)); \
+static void cpu_set_reserved_ttbr0(void)
+{
+ unsigned long ttbl = __pa(swapper_pg_dir);
+ unsigned long ttbh = 0;
+
+ /*
+ * Set TTBR0 to swapper_pg_dir. Note that swapper_pg_dir only contains
+ * global entries so the ASID value is not relevant.
+ */
+ asm volatile(
+ " mcrr p15, 0, %0, %1, c2 @ set TTBR0\n"
+ :
+ : "r" (ttbl), "r" (ttbh));
+ isb();
}
#else
-#define cpu_set_asid(asid) \
- asm(" mcr p15, 0, %0, c13, c0, 1\n" : : "r" (asid))
+static void cpu_set_reserved_ttbr0(void)
+{
+ u32 ttb;
+ /* Copy TTBR1 into TTBR0 */
+ asm volatile(
+ " mrc p15, 0, %0, c2, c0, 1 @ read TTBR1\n"
+ " mcr p15, 0, %0, c2, c0, 0 @ set TTBR0\n"
+ : "=r" (ttb));
+ isb();
+}
#endif
/*
* We fork()ed a process, and we need a new context for the child
- * to run in. We reserve version 0 for initial tasks so we will
- * always allocate an ASID. The ASID 0 is reserved for the TTBR
- * register changing sequence.
+ * to run in.
*/
void __init_new_context(struct task_struct *tsk, struct mm_struct *mm)
{
@@ -51,9 +63,7 @@ void __init_new_context(struct task_struct *tsk, struct mm_struct *mm)
static void flush_context(void)
{
- /* set the reserved ASID before flushing the TLB */
- cpu_set_asid(0);
- isb();
+ cpu_set_reserved_ttbr0();
local_flush_tlb_all();
if (icache_is_vivt_asid_tagged()) {
__flush_icache_all();
@@ -108,14 +118,13 @@ static void reset_context(void *info)
return;
smp_rmb();
- asid = cpu_last_asid + cpu + 1;
+ asid = cpu_last_asid + cpu;
flush_context();
set_mm_context(mm, asid);
/* set the new ASID */
- cpu_set_asid(mm->context.id);
- isb();
+ cpu_switch_mm(mm->pgd, mm);
}
#else
@@ -158,13 +167,13 @@ void __new_context(struct mm_struct *mm)
* to start a new version and flush the TLB.
*/
if (unlikely((asid & ~ASID_MASK) == 0)) {
- asid = cpu_last_asid + smp_processor_id() + 1;
+ asid = cpu_last_asid + smp_processor_id();
flush_context();
#ifdef CONFIG_SMP
smp_wmb();
smp_call_function(reset_context, NULL, 1);
#endif
- cpu_last_asid += NR_CPUS;
+ cpu_last_asid += NR_CPUS - 1;
}
set_mm_context(mm, asid);
diff --git a/arch/arm/mm/proc-v7-2level.S b/arch/arm/mm/proc-v7-2level.S
index 3a4b3e7b888..72270482a92 100644
--- a/arch/arm/mm/proc-v7-2level.S
+++ b/arch/arm/mm/proc-v7-2level.S
@@ -46,18 +46,16 @@ ENTRY(cpu_v7_switch_mm)
#ifdef CONFIG_ARM_ERRATA_430973
mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB
#endif
-#ifdef CONFIG_ARM_ERRATA_754322
- dsb
-#endif
- mcr p15, 0, r2, c13, c0, 1 @ set reserved context ID
- isb
-1: mcr p15, 0, r0, c2, c0, 0 @ set TTB 0
+ mrc p15, 0, r2, c2, c0, 1 @ load TTB 1
+ mcr p15, 0, r2, c2, c0, 0 @ into TTB 0
isb
#ifdef CONFIG_ARM_ERRATA_754322
dsb
#endif
mcr p15, 0, r1, c13, c0, 1 @ set context ID
isb
+ mcr p15, 0, r0, c2, c0, 0 @ set TTB 0
+ isb
#endif
mov pc, lr
ENDPROC(cpu_v7_switch_mm)