Linux Audio

Check our new training course

Loading...
v5.9
  1// SPDX-License-Identifier: GPL-2.0
  2// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
  3
  4#include <linux/init.h>
  5#include <linux/mm.h>
  6#include <linux/module.h>
  7#include <linux/sched.h>
  8
  9#include <asm/mmu_context.h>
 
 10#include <asm/setup.h>
 11
 12/*
 13 * One C-SKY MMU TLB entry contain two PFN/page entry, ie:
 14 * 1VPN -> 2PFN
 15 */
 16#define TLB_ENTRY_SIZE		(PAGE_SIZE * 2)
 17#define TLB_ENTRY_SIZE_MASK	(PAGE_MASK << 1)
 18
 19void flush_tlb_all(void)
 20{
 21	tlb_invalid_all();
 22}
 23
 24void flush_tlb_mm(struct mm_struct *mm)
 25{
 26#ifdef CONFIG_CPU_HAS_TLBI
 27	asm volatile("tlbi.asids %0"::"r"(cpu_asid(mm)));
 28#else
 29	tlb_invalid_all();
 30#endif
 31}
 32
 33/*
 34 * MMU operation regs only could invalid tlb entry in jtlb and we
 35 * need change asid field to invalid I-utlb & D-utlb.
 36 */
 37#ifndef CONFIG_CPU_HAS_TLBI
 38#define restore_asid_inv_utlb(oldpid, newpid) \
 39do { \
 40	if (oldpid == newpid) \
 41		write_mmu_entryhi(oldpid + 1); \
 42	write_mmu_entryhi(oldpid); \
 43} while (0)
 44#endif
 45
 46void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
 47			unsigned long end)
 48{
 49	unsigned long newpid = cpu_asid(vma->vm_mm);
 50
 51	start &= TLB_ENTRY_SIZE_MASK;
 52	end   += TLB_ENTRY_SIZE - 1;
 53	end   &= TLB_ENTRY_SIZE_MASK;
 54
 55#ifdef CONFIG_CPU_HAS_TLBI
 56	while (start < end) {
 57		asm volatile("tlbi.vas %0"::"r"(start | newpid));
 58		start += 2*PAGE_SIZE;
 59	}
 60	sync_is();
 61#else
 62	{
 63	unsigned long flags, oldpid;
 64
 65	local_irq_save(flags);
 66	oldpid = read_mmu_entryhi() & ASID_MASK;
 67	while (start < end) {
 68		int idx;
 69
 70		write_mmu_entryhi(start | newpid);
 71		start += 2*PAGE_SIZE;
 72		tlb_probe();
 73		idx = read_mmu_index();
 74		if (idx >= 0)
 75			tlb_invalid_indexed();
 76	}
 77	restore_asid_inv_utlb(oldpid, newpid);
 78	local_irq_restore(flags);
 79	}
 80#endif
 81}
 82
 83void flush_tlb_kernel_range(unsigned long start, unsigned long end)
 84{
 85	start &= TLB_ENTRY_SIZE_MASK;
 86	end   += TLB_ENTRY_SIZE - 1;
 87	end   &= TLB_ENTRY_SIZE_MASK;
 88
 89#ifdef CONFIG_CPU_HAS_TLBI
 90	while (start < end) {
 91		asm volatile("tlbi.vaas %0"::"r"(start));
 92		start += 2*PAGE_SIZE;
 93	}
 94	sync_is();
 95#else
 96	{
 97	unsigned long flags, oldpid;
 98
 99	local_irq_save(flags);
100	oldpid = read_mmu_entryhi() & ASID_MASK;
101	while (start < end) {
102		int idx;
103
104		write_mmu_entryhi(start | oldpid);
105		start += 2*PAGE_SIZE;
106		tlb_probe();
107		idx = read_mmu_index();
108		if (idx >= 0)
109			tlb_invalid_indexed();
110	}
111	restore_asid_inv_utlb(oldpid, oldpid);
112	local_irq_restore(flags);
113	}
114#endif
115}
116
117void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
118{
119	int newpid = cpu_asid(vma->vm_mm);
120
121	addr &= TLB_ENTRY_SIZE_MASK;
122
123#ifdef CONFIG_CPU_HAS_TLBI
124	asm volatile("tlbi.vas %0"::"r"(addr | newpid));
125	sync_is();
126#else
127	{
128	int oldpid, idx;
129	unsigned long flags;
130
131	local_irq_save(flags);
132	oldpid = read_mmu_entryhi() & ASID_MASK;
133	write_mmu_entryhi(addr | newpid);
134	tlb_probe();
135	idx = read_mmu_index();
136	if (idx >= 0)
137		tlb_invalid_indexed();
138
139	restore_asid_inv_utlb(oldpid, newpid);
140	local_irq_restore(flags);
141	}
142#endif
143}
144
145void flush_tlb_one(unsigned long addr)
146{
147	addr &= TLB_ENTRY_SIZE_MASK;
148
149#ifdef CONFIG_CPU_HAS_TLBI
150	asm volatile("tlbi.vaas %0"::"r"(addr));
151	sync_is();
152#else
153	{
154	int oldpid, idx;
155	unsigned long flags;
156
157	local_irq_save(flags);
158	oldpid = read_mmu_entryhi() & ASID_MASK;
159	write_mmu_entryhi(addr | oldpid);
160	tlb_probe();
161	idx = read_mmu_index();
162	if (idx >= 0)
163		tlb_invalid_indexed();
164
165	restore_asid_inv_utlb(oldpid, oldpid);
166	local_irq_restore(flags);
167	}
168#endif
169}
170EXPORT_SYMBOL(flush_tlb_one);
v5.4
  1// SPDX-License-Identifier: GPL-2.0
  2// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
  3
  4#include <linux/init.h>
  5#include <linux/mm.h>
  6#include <linux/module.h>
  7#include <linux/sched.h>
  8
  9#include <asm/mmu_context.h>
 10#include <asm/pgtable.h>
 11#include <asm/setup.h>
 12
 13/*
 14 * One C-SKY MMU TLB entry contain two PFN/page entry, ie:
 15 * 1VPN -> 2PFN
 16 */
 17#define TLB_ENTRY_SIZE		(PAGE_SIZE * 2)
 18#define TLB_ENTRY_SIZE_MASK	(PAGE_MASK << 1)
 19
 20void flush_tlb_all(void)
 21{
 22	tlb_invalid_all();
 23}
 24
 25void flush_tlb_mm(struct mm_struct *mm)
 26{
 27#ifdef CONFIG_CPU_HAS_TLBI
 28	asm volatile("tlbi.asids %0"::"r"(cpu_asid(mm)));
 29#else
 30	tlb_invalid_all();
 31#endif
 32}
 33
 34/*
 35 * MMU operation regs only could invalid tlb entry in jtlb and we
 36 * need change asid field to invalid I-utlb & D-utlb.
 37 */
 38#ifndef CONFIG_CPU_HAS_TLBI
 39#define restore_asid_inv_utlb(oldpid, newpid) \
 40do { \
 41	if (oldpid == newpid) \
 42		write_mmu_entryhi(oldpid + 1); \
 43	write_mmu_entryhi(oldpid); \
 44} while (0)
 45#endif
 46
 47void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
 48			unsigned long end)
 49{
 50	unsigned long newpid = cpu_asid(vma->vm_mm);
 51
 52	start &= TLB_ENTRY_SIZE_MASK;
 53	end   += TLB_ENTRY_SIZE - 1;
 54	end   &= TLB_ENTRY_SIZE_MASK;
 55
 56#ifdef CONFIG_CPU_HAS_TLBI
 57	while (start < end) {
 58		asm volatile("tlbi.vas %0"::"r"(start | newpid));
 59		start += 2*PAGE_SIZE;
 60	}
 61	sync_is();
 62#else
 63	{
 64	unsigned long flags, oldpid;
 65
 66	local_irq_save(flags);
 67	oldpid = read_mmu_entryhi() & ASID_MASK;
 68	while (start < end) {
 69		int idx;
 70
 71		write_mmu_entryhi(start | newpid);
 72		start += 2*PAGE_SIZE;
 73		tlb_probe();
 74		idx = read_mmu_index();
 75		if (idx >= 0)
 76			tlb_invalid_indexed();
 77	}
 78	restore_asid_inv_utlb(oldpid, newpid);
 79	local_irq_restore(flags);
 80	}
 81#endif
 82}
 83
 84void flush_tlb_kernel_range(unsigned long start, unsigned long end)
 85{
 86	start &= TLB_ENTRY_SIZE_MASK;
 87	end   += TLB_ENTRY_SIZE - 1;
 88	end   &= TLB_ENTRY_SIZE_MASK;
 89
 90#ifdef CONFIG_CPU_HAS_TLBI
 91	while (start < end) {
 92		asm volatile("tlbi.vaas %0"::"r"(start));
 93		start += 2*PAGE_SIZE;
 94	}
 95	sync_is();
 96#else
 97	{
 98	unsigned long flags, oldpid;
 99
100	local_irq_save(flags);
101	oldpid = read_mmu_entryhi() & ASID_MASK;
102	while (start < end) {
103		int idx;
104
105		write_mmu_entryhi(start | oldpid);
106		start += 2*PAGE_SIZE;
107		tlb_probe();
108		idx = read_mmu_index();
109		if (idx >= 0)
110			tlb_invalid_indexed();
111	}
112	restore_asid_inv_utlb(oldpid, oldpid);
113	local_irq_restore(flags);
114	}
115#endif
116}
117
118void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
119{
120	int newpid = cpu_asid(vma->vm_mm);
121
122	addr &= TLB_ENTRY_SIZE_MASK;
123
124#ifdef CONFIG_CPU_HAS_TLBI
125	asm volatile("tlbi.vas %0"::"r"(addr | newpid));
126	sync_is();
127#else
128	{
129	int oldpid, idx;
130	unsigned long flags;
131
132	local_irq_save(flags);
133	oldpid = read_mmu_entryhi() & ASID_MASK;
134	write_mmu_entryhi(addr | newpid);
135	tlb_probe();
136	idx = read_mmu_index();
137	if (idx >= 0)
138		tlb_invalid_indexed();
139
140	restore_asid_inv_utlb(oldpid, newpid);
141	local_irq_restore(flags);
142	}
143#endif
144}
145
146void flush_tlb_one(unsigned long addr)
147{
148	addr &= TLB_ENTRY_SIZE_MASK;
149
150#ifdef CONFIG_CPU_HAS_TLBI
151	asm volatile("tlbi.vaas %0"::"r"(addr));
152	sync_is();
153#else
154	{
155	int oldpid, idx;
156	unsigned long flags;
157
158	local_irq_save(flags);
159	oldpid = read_mmu_entryhi() & ASID_MASK;
160	write_mmu_entryhi(addr | oldpid);
161	tlb_probe();
162	idx = read_mmu_index();
163	if (idx >= 0)
164		tlb_invalid_indexed();
165
166	restore_asid_inv_utlb(oldpid, oldpid);
167	local_irq_restore(flags);
168	}
169#endif
170}
171EXPORT_SYMBOL(flush_tlb_one);