summaryrefslogtreecommitdiffstats
path: root/arch/csky/mm
diff options
context:
space:
mode:
authorGuo Ren2019-06-18 11:20:10 +0200
committerGuo Ren2019-07-19 08:21:36 +0200
commit9d35dc3006a9865eb5b55cc79df49933601131f8 (patch)
tree6f16dbd7f5111bcea394079e199bb68701459235 /arch/csky/mm
parentdt-bindings: csky: Add csky PMU bindings (diff)
downloadkernel-qcow2-linux-9d35dc3006a9865eb5b55cc79df49933601131f8.tar.gz
kernel-qcow2-linux-9d35dc3006a9865eb5b55cc79df49933601131f8.tar.xz
kernel-qcow2-linux-9d35dc3006a9865eb5b55cc79df49933601131f8.zip
csky: Revert mmu ASID mechanism
Current C-SKY ASID mechanism is from mips and it doesn't work well with multi-cores. ASID per core mechanism is not suitable for C-SKY SMP tlb maintain operations, eg: tlbi.vas need share the same asid in all processors and it'll invalid the tlb entry in all cores with the same asid. This patch is prepare for new ASID mechanism. Signed-off-by: Guo Ren <ren_guo@c-sky.com> Cc: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/csky/mm')
-rw-r--r--arch/csky/mm/init.c2
-rw-r--r--arch/csky/mm/tlb.c190
2 files changed, 7 insertions, 185 deletions
diff --git a/arch/csky/mm/init.c b/arch/csky/mm/init.c
index 66e597053488..eb0dc9e5065f 100644
--- a/arch/csky/mm/init.c
+++ b/arch/csky/mm/init.c
@@ -114,8 +114,6 @@ void __init pre_mmu_init(void)
TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir);
TLBMISS_HANDLER_SETUP_PGD_KERNEL(swapper_pg_dir);
- asid_cache(smp_processor_id()) = ASID_FIRST_VERSION;
-
/* Setup page mask to 4k */
write_mmu_pagemask(0);
}
diff --git a/arch/csky/mm/tlb.c b/arch/csky/mm/tlb.c
index 08b8394e5b8f..efae81ce7fbc 100644
--- a/arch/csky/mm/tlb.c
+++ b/arch/csky/mm/tlb.c
@@ -10,8 +10,6 @@
#include <asm/pgtable.h>
#include <asm/setup.h>
-#define CSKY_TLB_SIZE CONFIG_CPU_TLB_SIZE
-
void flush_tlb_all(void)
{
tlb_invalid_all();
@@ -19,201 +17,27 @@ void flush_tlb_all(void)
void flush_tlb_mm(struct mm_struct *mm)
{
- int cpu = smp_processor_id();
-
- if (cpu_context(cpu, mm) != 0)
- drop_mmu_context(mm, cpu);
-
tlb_invalid_all();
}
-#define restore_asid_inv_utlb(oldpid, newpid) \
-do { \
- if ((oldpid & ASID_MASK) == newpid) \
- write_mmu_entryhi(oldpid + 1); \
- write_mmu_entryhi(oldpid); \
-} while (0)
-
void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
- unsigned long end)
+ unsigned long end)
{
- struct mm_struct *mm = vma->vm_mm;
- int cpu = smp_processor_id();
-
- if (cpu_context(cpu, mm) != 0) {
- unsigned long size, flags;
- int newpid = cpu_asid(cpu, mm);
-
- local_irq_save(flags);
- size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
- size = (size + 1) >> 1;
- if (size <= CSKY_TLB_SIZE/2) {
- start &= (PAGE_MASK << 1);
- end += ((PAGE_SIZE << 1) - 1);
- end &= (PAGE_MASK << 1);
-#ifdef CONFIG_CPU_HAS_TLBI
- while (start < end) {
- asm volatile("tlbi.vaas %0"
- ::"r"(start | newpid));
- start += (PAGE_SIZE << 1);
- }
- sync_is();
-#else
- {
- int oldpid = read_mmu_entryhi();
-
- while (start < end) {
- int idx;
-
- write_mmu_entryhi(start | newpid);
- start += (PAGE_SIZE << 1);
- tlb_probe();
- idx = read_mmu_index();
- if (idx >= 0)
- tlb_invalid_indexed();
- }
- restore_asid_inv_utlb(oldpid, newpid);
- }
-#endif
- } else {
- drop_mmu_context(mm, cpu);
- }
- local_irq_restore(flags);
- }
+ tlb_invalid_all();
}
void flush_tlb_kernel_range(unsigned long start, unsigned long end)
{
- unsigned long size, flags;
-
- local_irq_save(flags);
- size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
- if (size <= CSKY_TLB_SIZE) {
- start &= (PAGE_MASK << 1);
- end += ((PAGE_SIZE << 1) - 1);
- end &= (PAGE_MASK << 1);
-#ifdef CONFIG_CPU_HAS_TLBI
- while (start < end) {
- asm volatile("tlbi.vaas %0"::"r"(start));
- start += (PAGE_SIZE << 1);
- }
- sync_is();
-#else
- {
- int oldpid = read_mmu_entryhi();
-
- while (start < end) {
- int idx;
-
- write_mmu_entryhi(start);
- start += (PAGE_SIZE << 1);
- tlb_probe();
- idx = read_mmu_index();
- if (idx >= 0)
- tlb_invalid_indexed();
- }
- restore_asid_inv_utlb(oldpid, 0);
- }
-#endif
- } else {
- flush_tlb_all();
- }
-
- local_irq_restore(flags);
+ tlb_invalid_all();
}
-void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
{
- int cpu = smp_processor_id();
- int newpid = cpu_asid(cpu, vma->vm_mm);
-
- if (!vma || cpu_context(cpu, vma->vm_mm) != 0) {
- page &= (PAGE_MASK << 1);
-
-#ifdef CONFIG_CPU_HAS_TLBI
- asm volatile("tlbi.vaas %0"::"r"(page | newpid));
- sync_is();
-#else
- {
- int oldpid, idx;
- unsigned long flags;
-
- local_irq_save(flags);
- oldpid = read_mmu_entryhi();
- write_mmu_entryhi(page | newpid);
- tlb_probe();
- idx = read_mmu_index();
- if (idx >= 0)
- tlb_invalid_indexed();
-
- restore_asid_inv_utlb(oldpid, newpid);
- local_irq_restore(flags);
- }
-#endif
- }
+ tlb_invalid_all();
}
-/*
- * Remove one kernel space TLB entry. This entry is assumed to be marked
- * global so we don't do the ASID thing.
- */
-void flush_tlb_one(unsigned long page)
+void flush_tlb_one(unsigned long addr)
{
- int oldpid;
-
- oldpid = read_mmu_entryhi();
- page &= (PAGE_MASK << 1);
-
-#ifdef CONFIG_CPU_HAS_TLBI
- page = page | (oldpid & 0xfff);
- asm volatile("tlbi.vaas %0"::"r"(page));
- sync_is();
-#else
- {
- int idx;
- unsigned long flags;
-
- page = page | (oldpid & 0xff);
-
- local_irq_save(flags);
- write_mmu_entryhi(page);
- tlb_probe();
- idx = read_mmu_index();
- if (idx >= 0)
- tlb_invalid_indexed();
- restore_asid_inv_utlb(oldpid, oldpid);
- local_irq_restore(flags);
- }
-#endif
+ tlb_invalid_all();
}
EXPORT_SYMBOL(flush_tlb_one);
-
-/* show current 32 jtlbs */
-void show_jtlb_table(void)
-{
- unsigned long flags;
- int entryhi, entrylo0, entrylo1;
- int entry;
- int oldpid;
-
- local_irq_save(flags);
- entry = 0;
- pr_info("\n\n\n");
-
- oldpid = read_mmu_entryhi();
- while (entry < CSKY_TLB_SIZE) {
- write_mmu_index(entry);
- tlb_read();
- entryhi = read_mmu_entryhi();
- entrylo0 = read_mmu_entrylo0();
- entrylo0 = entrylo0;
- entrylo1 = read_mmu_entrylo1();
- entrylo1 = entrylo1;
- pr_info("jtlb[%d]: entryhi - 0x%x; entrylo0 - 0x%x;"
- " entrylo1 - 0x%x\n",
- entry, entryhi, entrylo0, entrylo1);
- entry++;
- }
- write_mmu_entryhi(oldpid);
- local_irq_restore(flags);
-}