// SPDX-License-Identifier: GPL-2.0
/*
 * Based upon linux/arch/m68k/mm/sun3mmu.c
 * Based upon linux/arch/ppc/mm/mmu_context.c
 *
 * Implementations of mm routines specific to the Coldfire MMU.
 *
 * Copyright (c) 2008 Freescale Semiconductor, Inc.
 */

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/memblock.h>

#include <asm/setup.h>
#include <asm/page.h>
#include <asm/mmu_context.h>
#include <asm/mcf_pgalloc.h>
#include <asm/tlbflush.h>
#include <asm/pgalloc.h>

#define KMAPAREA(x)	((x >= VMALLOC_START) && (x < KMAP_END))

mm_context_t next_mmu_context;
unsigned long context_map[LAST_CONTEXT / BITS_PER_LONG + 1];
atomic_t nr_free_contexts;
struct mm_struct *context_mm[LAST_CONTEXT+1];
unsigned long num_pages;

/*
 * ColdFire paging_init derived from sun3.
 */
void __init paging_init(void)
{
	pgd_t *pg_dir;
	pte_t *pg_table;
	unsigned long address, size;
	unsigned long next_pgtable;
	unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0 };
	int i;

	empty_zero_page = memblock_alloc_or_panic(PAGE_SIZE, PAGE_SIZE);

	pg_dir = swapper_pg_dir;
	memset(swapper_pg_dir, 0, sizeof(swapper_pg_dir));

	size = num_pages * sizeof(pte_t);
	size = (size + PAGE_SIZE) & ~(PAGE_SIZE-1);
	next_pgtable = (unsigned long) memblock_alloc_or_panic(size, PAGE_SIZE);

	pg_dir += PAGE_OFFSET >> PGDIR_SHIFT;

	address = PAGE_OFFSET;
	while (address < (unsigned long)high_memory) {
		pg_table = (pte_t *) next_pgtable;
		next_pgtable += PTRS_PER_PTE * sizeof(pte_t);
		pgd_val(*pg_dir) = (unsigned long) pg_table;
		pg_dir++;

		/* now change pg_table to kernel virtual addresses */
		for (i = 0; i < PTRS_PER_PTE; ++i, ++pg_table) {
			pte_t pte = pfn_pte(virt_to_pfn((void *)address),
					    PAGE_INIT);
			if (address >= (unsigned long) high_memory)
				pte_val(pte) = 0;

			set_pte(pg_table, pte);
			address += PAGE_SIZE;
		}
	}

	current->mm = NULL;
	max_zone_pfn[ZONE_DMA] = PFN_DOWN(_ramend);
	free_area_init(max_zone_pfn);
}

int cf_tlb_miss(struct pt_regs *regs, int write, int dtlb, int extension_word)
{
	unsigned long flags, mmuar, mmutr;
	struct mm_struct *mm;
	pgd_t *pgd;
	p4d_t *p4d;
	pud_t *pud;
	pmd_t *pmd;
	pte_t *pte = NULL;
	int ret = -1;
	int asid;

	local_irq_save(flags);

	mmuar = (dtlb) ? mmu_read(MMUAR) :
		regs->pc + (extension_word * sizeof(long));

	mm = (!user_mode(regs) && KMAPAREA(mmuar)) ? &init_mm : current->mm;
	if (!mm)
		goto out;

	pgd = pgd_offset(mm, mmuar);
	if (pgd_none(*pgd))
		goto out;

	p4d = p4d_offset(pgd, mmuar);
	if (p4d_none(*p4d))
		goto out;

	pud = pud_offset(p4d, mmuar);
	if (pud_none(*pud))
		goto out;

	pmd = pmd_offset(pud, mmuar);
	if (pmd_none(*pmd))
		goto out;

	pte = (KMAPAREA(mmuar)) ? pte_offset_kernel(pmd, mmuar)
				: pte_offset_map(pmd, mmuar);
	if (!pte || pte_none(*pte) || !pte_present(*pte))
		goto out;

	if (write) {
		if (!pte_write(*pte))
			goto out;
		set_pte(pte, pte_mkdirty(*pte));
	}

	set_pte(pte, pte_mkyoung(*pte));
	asid = mm->context & 0xff;
	if (!pte_dirty(*pte) && !KMAPAREA(mmuar))
		set_pte(pte, pte_wrprotect(*pte));

	mmutr = (mmuar & PAGE_MASK) | (asid << MMUTR_IDN) | MMUTR_V;
	if ((mmuar < TASK_UNMAPPED_BASE) || (mmuar >= TASK_SIZE))
		mmutr |= (pte->pte & CF_PAGE_MMUTR_MASK) >> CF_PAGE_MMUTR_SHIFT;
	mmu_write(MMUTR, mmutr);

	mmu_write(MMUDR, (pte_val(*pte) & PAGE_MASK) |
		((pte->pte) & CF_PAGE_MMUDR_MASK) | MMUDR_SZ_8KB | MMUDR_X);

	if (dtlb)
		mmu_write(MMUOR, MMUOR_ACC | MMUOR_UAA);
	else
		mmu_write(MMUOR, MMUOR_ITLB | MMUOR_ACC | MMUOR_UAA);
	ret = 0;
out:
	if (pte && !KMAPAREA(mmuar))
		pte_unmap(pte);
	local_irq_restore(flags);
	return ret;
}

void __init cf_bootmem_alloc(void)
{
	unsigned long memstart;

	/* _rambase and _ramend will be naturally page aligned */
	m68k_memory[0].addr = _rambase;
	m68k_memory[0].size = _ramend - _rambase;

	memblock_add_node(m68k_memory[0].addr, m68k_memory[0].size, 0,
			  MEMBLOCK_NONE);

	/* compute total pages in system */
	num_pages = PFN_DOWN(_ramend - _rambase);

	/* page numbers */
	memstart = PAGE_ALIGN(_ramstart);
	min_low_pfn = PFN_DOWN(_rambase);
	max_pfn = max_low_pfn = PFN_DOWN(_ramend);
	high_memory = (void *)_ramend;

	/* Reserve kernel text/data/bss */
	memblock_reserve(_rambase, memstart - _rambase);

	m68k_virt_to_node_shift = fls(_ramend - 1) - 6;
	module_fixup(NULL, __start_fixup, __stop_fixup);

	/* setup node data */
	m68k_setup_node(0);
}

/*
 * Initialize the context management stuff.
 * The following was taken from arch/ppc/mmu_context.c
 */
void __init cf_mmu_context_init(void)
{
	/*
	 * Some processors have too few contexts to reserve one for
	 * init_mm, and require using context 0 for a normal task.
	 * Other processors reserve the use of context zero for the kernel.
	 * This code assumes FIRST_CONTEXT < 32.
	 */
	context_map[0] = (1 << FIRST_CONTEXT) - 1;
	next_mmu_context = FIRST_CONTEXT;
	atomic_set(&nr_free_contexts, LAST_CONTEXT - FIRST_CONTEXT + 1);
}

/*
 * Steal a context from a task that has one at the moment.
 * This isn't an LRU system, it just frees up each context in
 * turn (sort-of pseudo-random replacement :).  This would be the
 * place to implement an LRU scheme if anyone was motivated to do it.
 *  -- paulus
 */
void steal_context(void)
{
	struct mm_struct *mm;
	/*
	 * free up context `next_mmu_context'
	 * if we shouldn't free context 0, don't...
	 */
	if (next_mmu_context < FIRST_CONTEXT)
		next_mmu_context = FIRST_CONTEXT;
	mm = context_mm[next_mmu_context];
	flush_tlb_mm(mm);
	destroy_context(mm);
}

static const pgprot_t protection_map[16] = {
	[VM_NONE]					= PAGE_NONE,
	[VM_READ]					= __pgprot(CF_PAGE_VALID |
								   CF_PAGE_ACCESSED |
								   CF_PAGE_READABLE),
	[VM_WRITE]					= __pgprot(CF_PAGE_VALID |
								   CF_PAGE_ACCESSED |
								   CF_PAGE_WRITABLE),
	[VM_WRITE | VM_READ]				= __pgprot(CF_PAGE_VALID |
								   CF_PAGE_ACCESSED |
								   CF_PAGE_READABLE |
								   CF_PAGE_WRITABLE),
	[VM_EXEC]					= __pgprot(CF_PAGE_VALID |
								   CF_PAGE_ACCESSED |
								   CF_PAGE_EXEC),
	[VM_EXEC | VM_READ]				= __pgprot(CF_PAGE_VALID |
								   CF_PAGE_ACCESSED |
								   CF_PAGE_READABLE |
								   CF_PAGE_EXEC),
	[VM_EXEC | VM_WRITE]				= __pgprot(CF_PAGE_VALID |
								   CF_PAGE_ACCESSED |
								   CF_PAGE_WRITABLE |
								   CF_PAGE_EXEC),
	[VM_EXEC | VM_WRITE | VM_READ]			=  __pgprot(CF_PAGE_VALID |
								    CF_PAGE_ACCESSED |
								    CF_PAGE_READABLE |
								    CF_PAGE_WRITABLE |
								    CF_PAGE_EXEC),
	[VM_SHARED]					= PAGE_NONE,
	[VM_SHARED | VM_READ]				= __pgprot(CF_PAGE_VALID |
								   CF_PAGE_ACCESSED |
								   CF_PAGE_READABLE),
	[VM_SHARED | VM_WRITE]				= PAGE_SHARED,
	[VM_SHARED | VM_WRITE | VM_READ]		= __pgprot(CF_PAGE_VALID |
								   CF_PAGE_ACCESSED |
								   CF_PAGE_READABLE |
								   CF_PAGE_SHARED),
	[VM_SHARED | VM_EXEC]				= __pgprot(CF_PAGE_VALID |
								   CF_PAGE_ACCESSED |
								   CF_PAGE_EXEC),
	[VM_SHARED | VM_EXEC | VM_READ]			= __pgprot(CF_PAGE_VALID |
								   CF_PAGE_ACCESSED |
								   CF_PAGE_READABLE |
								   CF_PAGE_EXEC),
	[VM_SHARED | VM_EXEC | VM_WRITE]		= __pgprot(CF_PAGE_VALID |
								   CF_PAGE_ACCESSED |
								   CF_PAGE_SHARED |
								   CF_PAGE_EXEC),
	[VM_SHARED | VM_EXEC | VM_WRITE | VM_READ]	= __pgprot(CF_PAGE_VALID |
								   CF_PAGE_ACCESSED |
								   CF_PAGE_READABLE |
								   CF_PAGE_SHARED |
								   CF_PAGE_EXEC)
};
DECLARE_VM_GET_PAGE_PROT
