// SPDX-License-Identifier: GPL-2.0
/*
 *  Copyright (C) 2005,2006,2007,2008,2009 Imagination Technologies
 *
 * Meta 1 MMU handling code.
 *
 */

#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/io.h>

#include <asm/mmu.h>

#define DM3_BASE (LINSYSDIRECT_BASE + (MMCU_DIRECTMAPn_ADDR_SCALE * 3))

/*
 * This contains the physical address of the top level 2k pgd table.
 */
static unsigned long mmu_base_phys;

/*
 * Given a physical address, return a mapped virtual address that can be used
 * to access that location.
 * In practice, we use the DirectMap region to make this happen.
 */
static unsigned long map_addr(unsigned long phys)
{
	static unsigned long dm_base = 0xFFFFFFFF;
	int offset;

	offset = phys - dm_base;

	/* Are we in the current map range ? */
	if ((offset < 0) || (offset >= MMCU_DIRECTMAPn_ADDR_SCALE)) {
		/* Calculate new DM area */
		dm_base = phys & ~(MMCU_DIRECTMAPn_ADDR_SCALE - 1);

		/* Actually map it in! */
		metag_out32(dm_base, MMCU_DIRECTMAP3_ADDR);

		/* And calculate how far into that area our reference is */
		offset = phys - dm_base;
	}

	return DM3_BASE + offset;
}

/*
 * Return the physical address of the base of our pgd table.
 */
static inline unsigned long __get_mmu_base(void)
{
	unsigned long base_phys;
	unsigned int stride;

	if (is_global_space(PAGE_OFFSET))
		stride = 4;
	else
		stride = hard_processor_id();	/* [0..3] */

	base_phys = metag_in32(MMCU_TABLE_PHYS_ADDR);
	base_phys += (0x800 * stride);

	return base_phys;
}

/* Given a virtual address, return the virtual address of the relevant pgd */
static unsigned long pgd_entry_addr(unsigned long virt)
{
	unsigned long pgd_phys;
	unsigned long pgd_virt;

	if (!mmu_base_phys)
		mmu_base_phys = __get_mmu_base();

	/*
	 * Are we trying to map a global address.  If so, then index
	 * the global pgd table instead of our local one.
	 */
	if (is_global_space(virt)) {
		/* Scale into 2gig map */
		virt &= ~0x80000000;
	}

	/* Base of the pgd table plus our 4Meg entry, 4bytes each */
	pgd_phys = mmu_base_phys + ((virt >> PGDIR_SHIFT) * 4);

	pgd_virt = map_addr(pgd_phys);

	return pgd_virt;
}

/* Given a virtual address, return the virtual address of the relevant pte */
static unsigned long pgtable_entry_addr(unsigned long virt)
{
	unsigned long pgtable_phys;
	unsigned long pgtable_virt, pte_virt;

	/* Find the physical address of the 4MB page table*/
	pgtable_phys = metag_in32(pgd_entry_addr(virt)) & MMCU_ENTRY_ADDR_BITS;

	/* Map it to a virtual address */
	pgtable_virt = map_addr(pgtable_phys);

	/* And index into it for our pte */
	pte_virt = pgtable_virt + ((virt >> PAGE_SHIFT) & 0x3FF) * 4;

	return pte_virt;
}

unsigned long mmu_read_first_level_page(unsigned long vaddr)
{
	return metag_in32(pgd_entry_addr(vaddr));
}

unsigned long mmu_read_second_level_page(unsigned long vaddr)
{
	return metag_in32(pgtable_entry_addr(vaddr));
}

unsigned long mmu_get_base(void)
{
	static unsigned long __base;

	/* Find the base of our MMU pgd table */
	if (!__base)
		__base = pgd_entry_addr(0);

	return __base;
}

void __init mmu_init(unsigned long mem_end)
{
	unsigned long entry, addr;
	pgd_t *p_swapper_pg_dir;

	/*
	 * Now copy over any MMU pgd entries already in the mmu page tables
	 * over to our root init process (swapper_pg_dir) map.  This map is
	 * then inherited by all other processes, which means all processes
	 * inherit a map of the kernel space.
	 */
	addr = PAGE_OFFSET;
	entry = pgd_index(PAGE_OFFSET);
	p_swapper_pg_dir = pgd_offset_k(0) + entry;

	while (addr <= META_MEMORY_LIMIT) {
		unsigned long pgd_entry;
		/* copy over the current MMU value */
		pgd_entry = mmu_read_first_level_page(addr);
		pgd_val(*p_swapper_pg_dir) = pgd_entry;

		p_swapper_pg_dir++;
		addr += PGDIR_SIZE;
	}
}
