Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * TLB flushing operations for SH with an MMU.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *  Copyright (C) 1999  Niibe Yutaka
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *  Copyright (C) 2003  Paul Mundt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * License.  See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <asm/mmu_context.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <asm/tlbflush.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 	unsigned int cpu = smp_processor_id();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	if (vma->vm_mm && cpu_context(cpu, vma->vm_mm) != NO_CONTEXT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 		unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 		unsigned long asid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 		unsigned long saved_asid = MMU_NO_ASID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 		asid = cpu_asid(cpu, vma->vm_mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 		page &= PAGE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 		local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 		if (vma->vm_mm != current->mm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 			saved_asid = get_asid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 			set_asid(asid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 		local_flush_tlb_one(asid, page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 		if (saved_asid != MMU_NO_ASID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 			set_asid(saved_asid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 		local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 			   unsigned long end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	struct mm_struct *mm = vma->vm_mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	unsigned int cpu = smp_processor_id();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	if (cpu_context(cpu, mm) != NO_CONTEXT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		if (size > (MMU_NTLB_ENTRIES/4)) { /* Too many TLB to flush */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 			cpu_context(cpu, mm) = NO_CONTEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 			if (mm == current->mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 				activate_context(mm, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 			unsigned long asid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 			unsigned long saved_asid = MMU_NO_ASID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 			asid = cpu_asid(cpu, mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 			start &= PAGE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 			end += (PAGE_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 			end &= PAGE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 			if (mm != current->mm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 				saved_asid = get_asid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 				set_asid(asid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 			while (start < end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 				local_flush_tlb_one(asid, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 				start += PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 			if (saved_asid != MMU_NO_ASID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 				set_asid(saved_asid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	unsigned int cpu = smp_processor_id();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	if (size > (MMU_NTLB_ENTRIES/4)) { /* Too many TLB to flush */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		local_flush_tlb_all();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		unsigned long asid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		unsigned long saved_asid = get_asid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		asid = cpu_asid(cpu, &init_mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		start &= PAGE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		end += (PAGE_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		end &= PAGE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		set_asid(asid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		while (start < end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 			local_flush_tlb_one(asid, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 			start += PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		set_asid(saved_asid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) void local_flush_tlb_mm(struct mm_struct *mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	unsigned int cpu = smp_processor_id();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	/* Invalidate all TLB of this process. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	/* Instead of invalidating each TLB, we get new MMU context. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	if (cpu_context(cpu, mm) != NO_CONTEXT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		cpu_context(cpu, mm) = NO_CONTEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		if (mm == current->mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 			activate_context(mm, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) void __flush_tlb_global(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	 * This is the most destructive of the TLB flushing options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	 * and will tear down all of the UTLB/ITLB mappings, including
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	 * wired entries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	__raw_writel(__raw_readl(MMUCR) | MMUCR_TI, MMUCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }