summaryrefslogtreecommitdiff
path: root/arch/powerpc/mm/8xx_mmu.c
diff options
context:
space:
mode:
authorChristophe Leroy <christophe.leroy@c-s.fr>2016-02-09 17:08:18 +0100
committerScott Wood <oss@buserror.net>2016-03-11 17:20:11 -0600
commita7761fe48993f103d6deac6037bf786bd1db0501 (patch)
tree35566d489c8b6ce8c34541b5f048eaabd84cd691 /arch/powerpc/mm/8xx_mmu.c
parent63e9e1c28fa6fe714364c7817e60dbaed3cec95e (diff)
powerpc/8xx: rewrite set_context() in C
There is no real need to have set_context() in assembly. Now that we have mtspr() handling CPU6 ERRATA directly, we can rewrite set_context() in C language for easier maintenance. Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr> Signed-off-by: Scott Wood <oss@buserror.net>
Diffstat (limited to 'arch/powerpc/mm/8xx_mmu.c')
-rw-r--r--arch/powerpc/mm/8xx_mmu.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/arch/powerpc/mm/8xx_mmu.c b/arch/powerpc/mm/8xx_mmu.c
index a84f5ebed1c1..606d2319a44f 100644
--- a/arch/powerpc/mm/8xx_mmu.c
+++ b/arch/powerpc/mm/8xx_mmu.c
@@ -98,3 +98,37 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base,
memblock_set_current_limit(min_t(u64, first_memblock_size, 0x00800000));
#endif
}
+
+/*
+ * Set up to use a given MMU context.
+ * id is context number, pgd is PGD pointer.
+ *
+ * We place the physical address of the new task page directory loaded
+ * into the MMU base register, and set the ASID compare register with
+ * the new "context."
+ */
+void set_context(unsigned long id, pgd_t *pgd)
+{
+ s16 offset = (s16)(__pa(swapper_pg_dir));
+
+#ifdef CONFIG_BDI_SWITCH
+ pgd_t **ptr = *(pgd_t ***)(KERNELBASE + 0xf0);
+
+ /* Context switch the PTE pointer for the Abatron BDI2000.
+ * The PGDIR is passed as second argument.
+ */
+ *(ptr + 1) = pgd;
+#endif
+
+ /* Register M_TW will contain base address of level 1 table minus the
+ * lower part of the kernel PGDIR base address, so that all accesses to
+ * level 1 table are done relative to lower part of kernel PGDIR base
+ * address.
+ */
+ mtspr(SPRN_M_TW, __pa(pgd) - offset);
+
+ /* Update context */
+ mtspr(SPRN_M_CASID, id);
+ /* sync */
+ mb();
+}