/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * s390x MMU
 *
 * Copyright (c) 2017 Red Hat Inc
 *
 * Authors:
 *  David Hildenbrand <david@redhat.com>
 */

#include <libcflat.h>
#include <asm/pgtable.h>
#include <asm/arch_def.h>
#include <asm/barrier.h>
#include <vmalloc.h>
#include "mmu.h"

static pgd_t *table_root;

void configure_dat(int enable)
{
	uint64_t mask;

	if (enable)
		mask = extract_psw_mask() | PSW_MASK_DAT;
	else
		mask = extract_psw_mask() & ~PSW_MASK_DAT;

	load_psw_mask(mask);
}

static void mmu_enable(pgd_t *pgtable)
{
	struct lowcore *lc = NULL;
	const uint64_t asce = __pa(pgtable) | ASCE_DT_REGION1 |
			      REGION_TABLE_LENGTH;

	/* set primary asce */
	lctlg(1, asce);
	assert(stctg(1) == asce);

	/* enable dat (primary == 0 set as default) */
	configure_dat(1);

	/* we can now also use DAT unconditionally in our PGM handler */
	lc->pgm_new_psw.mask |= PSW_MASK_DAT;
}

static pteval_t *get_pte(pgd_t *pgtable, uintptr_t vaddr)
{
	pgd_t *pgd = pgd_offset(pgtable, vaddr);
	p4d_t *p4d = p4d_alloc(pgd, vaddr);
	pud_t *pud = pud_alloc(p4d, vaddr);
	pmd_t *pmd = pmd_alloc(pud, vaddr);
	pte_t *pte = pte_alloc(pmd, vaddr);

	return &pte_val(*pte);
}

phys_addr_t virt_to_pte_phys(pgd_t *pgtable, void *vaddr)
{
	return (*get_pte(pgtable, (uintptr_t)vaddr) & PAGE_MASK) +
	       ((unsigned long)vaddr & ~PAGE_MASK);
}

static pteval_t *set_pte(pgd_t *pgtable, pteval_t val, void *vaddr)
{
	pteval_t *p_pte = get_pte(pgtable, (uintptr_t)vaddr);

	/* first flush the old entry (if we're replacing anything) */
	if (!(*p_pte & PAGE_ENTRY_I))
		ipte((uintptr_t)vaddr, p_pte);

	*p_pte = val;
	return p_pte;
}

pteval_t *install_page(pgd_t *pgtable, phys_addr_t phys, void *vaddr)
{
	return set_pte(pgtable, __pa(phys), vaddr);
}

void protect_page(void *vaddr, unsigned long prot)
{
	pteval_t *p_pte = get_pte(table_root, (uintptr_t)vaddr);
	pteval_t n_pte = *p_pte | prot;

	set_pte(table_root, n_pte, vaddr);
}

void unprotect_page(void *vaddr, unsigned long prot)
{
	pteval_t *p_pte = get_pte(table_root, (uintptr_t)vaddr);
	pteval_t n_pte = *p_pte & ~prot;

	set_pte(table_root, n_pte, vaddr);
}

void protect_range(void *start, unsigned long len, unsigned long prot)
{
	uintptr_t curr = (uintptr_t)start & PAGE_MASK;

	len &= PAGE_MASK;
	for (; len; len -= PAGE_SIZE, curr += PAGE_SIZE)
		protect_page((void *)curr, prot);
}

void unprotect_range(void *start, unsigned long len, unsigned long prot)
{
	uintptr_t curr = (uintptr_t)start & PAGE_MASK;

	len &= PAGE_MASK;
	for (; len; len -= PAGE_SIZE, curr += PAGE_SIZE)
		unprotect_page((void *)curr, prot);
}

static void setup_identity(pgd_t *pgtable, phys_addr_t start_addr,
			   phys_addr_t end_addr)
{
	phys_addr_t cur;

	start_addr &= PAGE_MASK;
	for (cur = start_addr; true; cur += PAGE_SIZE) {
		if (start_addr < end_addr && cur >= end_addr)
			break;
		if (start_addr > end_addr && cur <= end_addr)
			break;
		install_page(pgtable, cur, __va(cur));
	}
}

void *setup_mmu(phys_addr_t phys_end){
	pgd_t *page_root;

	/* allocate a region-1 table */
	page_root = pgd_alloc_one();

	/* map all physical memory 1:1 */
	setup_identity(page_root, 0, phys_end);

	/* generate 128MB of invalid adresses at the end (for testing PGM) */
	init_alloc_vpage((void *) -(1UL << 27));
	setup_identity(page_root, -(1UL << 27), 0);

	/* finally enable DAT with the new table */
	mmu_enable(page_root);
	table_root = page_root;
	return page_root;
}
