// SPDX-License-Identifier: GPL-2.0
/*
 *  linux/arch/m68k/mm/cache.c
 *
 *  Instruction cache handling
 *
 *  Copyright (C) 1995  Hamish Macdonald
 */

#include <linux/module.h>
#include <asm/cacheflush.h>
#include <asm/traps.h>


static unsigned long virt_to_phys_slow(unsigned long vaddr)
{
	if (CPU_IS_060) {
		unsigned long paddr;

		/* The PLPAR instruction causes an access error if the translation
		 * is not possible. To catch this we use the same exception mechanism
		 * as for user space accesses in <asm/uaccess.h>. */
		asm volatile (".chip 68060\n"
			      "1: plpar (%0)\n"
			      ".chip 68k\n"
			      "2:\n"
			      ".section .fixup,\"ax\"\n"
			      "   .even\n"
			      "3: sub.l %0,%0\n"
			      "   jra 2b\n"
			      ".previous\n"
			      ".section __ex_table,\"a\"\n"
			      "   .align 4\n"
			      "   .long 1b,3b\n"
			      ".previous"
			      : "=a" (paddr)
			      : "0" (vaddr));
		return paddr;
	} else if (CPU_IS_040) {
		unsigned long mmusr;

		asm volatile (".chip 68040\n\t"
			      "ptestr (%1)\n\t"
			      "movec %%mmusr, %0\n\t"
			      ".chip 68k"
			      : "=r" (mmusr)
			      : "a" (vaddr));

		if (mmusr & MMU_R_040)
			return (mmusr & PAGE_MASK) | (vaddr & ~PAGE_MASK);
	} else {
		unsigned short mmusr;
		unsigned long *descaddr;

		asm volatile ("ptestr %3,%2@,#7,%0\n\t"
			      "pmove %%psr,%1"
			      : "=a&" (descaddr), "=m" (mmusr)
			      : "a" (vaddr), "d" (get_fs().seg));
		if (mmusr & (MMU_I|MMU_B|MMU_L))
			return 0;
		descaddr = phys_to_virt((unsigned long)descaddr);
		switch (mmusr & MMU_NUM) {
		case 1:
			return (*descaddr & 0xfe000000) | (vaddr & 0x01ffffff);
		case 2:
			return (*descaddr & 0xfffc0000) | (vaddr & 0x0003ffff);
		case 3:
			return (*descaddr & PAGE_MASK) | (vaddr & ~PAGE_MASK);
		}
	}
	return 0;
}

/* Push n pages at kernel virtual address and clear the icache */
/* RZ: use cpush %bc instead of cpush %dc, cinv %ic */
void flush_icache_user_range(unsigned long address, unsigned long endaddr)
{
	if (CPU_IS_COLDFIRE) {
		unsigned long start, end;
		start = address & ICACHE_SET_MASK;
		end = endaddr & ICACHE_SET_MASK;
		if (start > end) {
			flush_cf_icache(0, end);
			end = ICACHE_MAX_ADDR;
		}
		flush_cf_icache(start, end);
	} else if (CPU_IS_040_OR_060) {
		address &= PAGE_MASK;

		do {
			asm volatile ("nop\n\t"
				      ".chip 68040\n\t"
				      "cpushp %%bc,(%0)\n\t"
				      ".chip 68k"
				      : : "a" (virt_to_phys_slow(address)));
			address += PAGE_SIZE;
		} while (address < endaddr);
	} else {
		unsigned long tmp;
		asm volatile ("movec %%cacr,%0\n\t"
			      "orw %1,%0\n\t"
			      "movec %0,%%cacr"
			      : "=&d" (tmp)
			      : "di" (FLUSH_I));
	}
}

void flush_icache_range(unsigned long address, unsigned long endaddr)
{
	mm_segment_t old_fs = get_fs();

	set_fs(KERNEL_DS);
	flush_icache_user_range(address, endaddr);
	set_fs(old_fs);
}
EXPORT_SYMBOL(flush_icache_range);

void flush_icache_user_page(struct vm_area_struct *vma, struct page *page,
			     unsigned long addr, int len)
{
	if (CPU_IS_COLDFIRE) {
		unsigned long start, end;
		start = addr & ICACHE_SET_MASK;
		end = (addr + len) & ICACHE_SET_MASK;
		if (start > end) {
			flush_cf_icache(0, end);
			end = ICACHE_MAX_ADDR;
		}
		flush_cf_icache(start, end);

	} else if (CPU_IS_040_OR_060) {
		asm volatile ("nop\n\t"
			      ".chip 68040\n\t"
			      "cpushp %%bc,(%0)\n\t"
			      ".chip 68k"
			      : : "a" (page_to_phys(page)));
	} else {
		unsigned long tmp;
		asm volatile ("movec %%cacr,%0\n\t"
			      "orw %1,%0\n\t"
			      "movec %0,%%cacr"
			      : "=&d" (tmp)
			      : "di" (FLUSH_I));
	}
}

