18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * OpenRISC Linux
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Linux architectural port borrowing liberally from similar works of
68c2ecf20Sopenharmony_ci * others.  All original copyrights apply as per the original source
78c2ecf20Sopenharmony_ci * declaration.
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci * OpenRISC implementation:
108c2ecf20Sopenharmony_ci * Copyright (C) Jan Henrik Weinstock <jan.weinstock@rwth-aachen.de>
118c2ecf20Sopenharmony_ci * et al.
128c2ecf20Sopenharmony_ci */
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#ifndef __ASM_CACHEFLUSH_H
158c2ecf20Sopenharmony_ci#define __ASM_CACHEFLUSH_H
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci#include <linux/mm.h>
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci/*
208c2ecf20Sopenharmony_ci * Helper function for flushing or invalidating entire pages from data
218c2ecf20Sopenharmony_ci * and instruction caches. SMP needs a little extra work, since we need
228c2ecf20Sopenharmony_ci * to flush the pages on all cpus.
238c2ecf20Sopenharmony_ci */
248c2ecf20Sopenharmony_ciextern void local_dcache_page_flush(struct page *page);
258c2ecf20Sopenharmony_ciextern void local_icache_page_inv(struct page *page);
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci/*
288c2ecf20Sopenharmony_ci * Data cache flushing always happen on the local cpu. Instruction cache
298c2ecf20Sopenharmony_ci * invalidations need to be broadcasted to all other cpu in the system in
308c2ecf20Sopenharmony_ci * case of SMP configurations.
318c2ecf20Sopenharmony_ci */
328c2ecf20Sopenharmony_ci#ifndef CONFIG_SMP
338c2ecf20Sopenharmony_ci#define dcache_page_flush(page)      local_dcache_page_flush(page)
348c2ecf20Sopenharmony_ci#define icache_page_inv(page)        local_icache_page_inv(page)
358c2ecf20Sopenharmony_ci#else  /* CONFIG_SMP */
368c2ecf20Sopenharmony_ci#define dcache_page_flush(page)      local_dcache_page_flush(page)
378c2ecf20Sopenharmony_ci#define icache_page_inv(page)        smp_icache_page_inv(page)
388c2ecf20Sopenharmony_ciextern void smp_icache_page_inv(struct page *page);
398c2ecf20Sopenharmony_ci#endif /* CONFIG_SMP */
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci/*
428c2ecf20Sopenharmony_ci * Synchronizes caches. Whenever a cpu writes executable code to memory, this
438c2ecf20Sopenharmony_ci * should be called to make sure the processor sees the newly written code.
448c2ecf20Sopenharmony_ci */
458c2ecf20Sopenharmony_cistatic inline void sync_icache_dcache(struct page *page)
468c2ecf20Sopenharmony_ci{
478c2ecf20Sopenharmony_ci	if (!IS_ENABLED(CONFIG_DCACHE_WRITETHROUGH))
488c2ecf20Sopenharmony_ci		dcache_page_flush(page);
498c2ecf20Sopenharmony_ci	icache_page_inv(page);
508c2ecf20Sopenharmony_ci}
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci/*
538c2ecf20Sopenharmony_ci * Pages with this bit set need not be flushed/invalidated, since
548c2ecf20Sopenharmony_ci * they have not changed since last flush. New pages start with
558c2ecf20Sopenharmony_ci * PG_arch_1 not set and are therefore dirty by default.
568c2ecf20Sopenharmony_ci */
578c2ecf20Sopenharmony_ci#define PG_dc_clean                  PG_arch_1
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
608c2ecf20Sopenharmony_cistatic inline void flush_dcache_page(struct page *page)
618c2ecf20Sopenharmony_ci{
628c2ecf20Sopenharmony_ci	clear_bit(PG_dc_clean, &page->flags);
638c2ecf20Sopenharmony_ci}
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci#define flush_icache_user_page(vma, page, addr, len)	\
668c2ecf20Sopenharmony_cido {							\
678c2ecf20Sopenharmony_ci	if (vma->vm_flags & VM_EXEC)			\
688c2ecf20Sopenharmony_ci		sync_icache_dcache(page);		\
698c2ecf20Sopenharmony_ci} while (0)
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci#include <asm-generic/cacheflush.h>
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci#endif /* __ASM_CACHEFLUSH_H */
74