/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_POWERPC_BOOK3S_64_HASH_H
#define _ASM_POWERPC_BOOK3S_64_HASH_H
#ifdef __KERNEL__

#include <asm/asm-const.h>

/*
 * Common bits between 4K and 64K pages in a linux-style PTE.
 * Additional bits may be defined in pgtable-hash64-*.h
 *
 */
#define H_PTE_NONE_MASK		_PAGE_HPTEFLAGS

#ifdef CONFIG_PPC_64K_PAGES
#include <asm/book3s/64/hash-64k.h>
#else
#include <asm/book3s/64/hash-4k.h>
#endif

/* Bits to set in a PMD/PUD/PGD entry valid bit*/
#define HASH_PMD_VAL_BITS		(0x8000000000000000UL)
#define HASH_PUD_VAL_BITS		(0x8000000000000000UL)
#define HASH_PGD_VAL_BITS		(0x8000000000000000UL)

/*
 * Size of EA range mapped by our pagetables.
 */
#define H_PGTABLE_EADDR_SIZE	(H_PTE_INDEX_SIZE + H_PMD_INDEX_SIZE + \
				 H_PUD_INDEX_SIZE + H_PGD_INDEX_SIZE + PAGE_SHIFT)
#define H_PGTABLE_RANGE		(ASM_CONST(1) << H_PGTABLE_EADDR_SIZE)
/*
 * Top 2 bits are ignored in page table walk.
 */
#define EA_MASK			(~(0xcUL << 60))

/*
 * We store the slot details in the second half of page table.
 * Increase the pud level table so that hugetlb ptes can be stored
 * at pud level.
 */
#if defined(CONFIG_HUGETLB_PAGE) &&  defined(CONFIG_PPC_64K_PAGES)
#define H_PUD_CACHE_INDEX	(H_PUD_INDEX_SIZE + 1)
#else
#define H_PUD_CACHE_INDEX	(H_PUD_INDEX_SIZE)
#endif

/*
 * +------------------------------+
 * |                              |
 * |                              |
 * |                              |
 * +------------------------------+  Kernel virtual map end (0xc00e000000000000)
 * |                              |
 * |                              |
 * |      512TB/16TB of vmemmap   |
 * |                              |
 * |                              |
 * +------------------------------+  Kernel vmemmap  start
 * |                              |
 * |      512TB/16TB of IO map    |
 * |                              |
 * +------------------------------+  Kernel IO map start
 * |                              |
 * |      512TB/16TB of vmap      |
 * |                              |
 * +------------------------------+  Kernel virt start (0xc008000000000000)
 * |                              |
 * |                              |
 * |                              |
 * +------------------------------+  Kernel linear (0xc.....)
 */

#define H_VMALLOC_START		H_KERN_VIRT_START
#define H_VMALLOC_SIZE		H_KERN_MAP_SIZE
#define H_VMALLOC_END		(H_VMALLOC_START + H_VMALLOC_SIZE)

#define H_KERN_IO_START		H_VMALLOC_END
#define H_KERN_IO_SIZE		H_KERN_MAP_SIZE
#define H_KERN_IO_END		(H_KERN_IO_START + H_KERN_IO_SIZE)

#define H_VMEMMAP_START		H_KERN_IO_END
#define H_VMEMMAP_SIZE		H_KERN_MAP_SIZE
#define H_VMEMMAP_END		(H_VMEMMAP_START + H_VMEMMAP_SIZE)

#define NON_LINEAR_REGION_ID(ea)	((((unsigned long)ea - H_KERN_VIRT_START) >> REGION_SHIFT) + 2)

/*
 * Region IDs
 */
#define USER_REGION_ID		0
#define LINEAR_MAP_REGION_ID	1
#define VMALLOC_REGION_ID	NON_LINEAR_REGION_ID(H_VMALLOC_START)
#define IO_REGION_ID		NON_LINEAR_REGION_ID(H_KERN_IO_START)
#define VMEMMAP_REGION_ID	NON_LINEAR_REGION_ID(H_VMEMMAP_START)
#define INVALID_REGION_ID	(VMEMMAP_REGION_ID + 1)

/*
 * Defines the address of the vmemap area, in its own region on
 * hash table CPUs.
 */
#ifdef CONFIG_PPC_MM_SLICES
#define HAVE_ARCH_UNMAPPED_AREA
#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
#endif /* CONFIG_PPC_MM_SLICES */

/* PTEIDX nibble */
#define _PTEIDX_SECONDARY	0x8
#define _PTEIDX_GROUP_IX	0x7

#define H_PMD_BAD_BITS		(PTE_TABLE_SIZE-1)
#define H_PUD_BAD_BITS		(PMD_TABLE_SIZE-1)

#ifndef __ASSEMBLY__
static inline int get_region_id(unsigned long ea)
{
	int region_id;
	int id = (ea >> 60UL);

	if (id == 0)
		return USER_REGION_ID;

	if (id != (PAGE_OFFSET >> 60))
		return INVALID_REGION_ID;

	if (ea < H_KERN_VIRT_START)
		return LINEAR_MAP_REGION_ID;

	BUILD_BUG_ON(NON_LINEAR_REGION_ID(H_VMALLOC_START) != 2);

	region_id = NON_LINEAR_REGION_ID(ea);
	return region_id;
}

#define	hash__pmd_bad(pmd)		(pmd_val(pmd) & H_PMD_BAD_BITS)
#define	hash__pud_bad(pud)		(pud_val(pud) & H_PUD_BAD_BITS)
static inline int hash__p4d_bad(p4d_t p4d)
{
	return (p4d_val(p4d) == 0);
}
#ifdef CONFIG_STRICT_KERNEL_RWX
extern void hash__mark_rodata_ro(void);
extern void hash__mark_initmem_nx(void);
#endif

extern void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
			    pte_t *ptep, unsigned long pte, int huge);
unsigned long htab_convert_pte_flags(unsigned long pteflags, unsigned long flags);
/* Atomic PTE updates */
static inline unsigned long hash__pte_update(struct mm_struct *mm,
					 unsigned long addr,
					 pte_t *ptep, unsigned long clr,
					 unsigned long set,
					 int huge)
{
	__be64 old_be, tmp_be;
	unsigned long old;

	__asm__ __volatile__(
	"1:	ldarx	%0,0,%3		# pte_update\n\
	and.	%1,%0,%6\n\
	bne-	1b \n\
	andc	%1,%0,%4 \n\
	or	%1,%1,%7\n\
	stdcx.	%1,0,%3 \n\
	bne-	1b"
	: "=&r" (old_be), "=&r" (tmp_be), "=m" (*ptep)
	: "r" (ptep), "r" (cpu_to_be64(clr)), "m" (*ptep),
	  "r" (cpu_to_be64(H_PAGE_BUSY)), "r" (cpu_to_be64(set))
	: "cc" );
	/* huge pages use the old page table lock */
	if (!huge)
		assert_pte_locked(mm, addr);

	old = be64_to_cpu(old_be);
	if (old & H_PAGE_HASHPTE)
		hpte_need_flush(mm, addr, ptep, old, huge);

	return old;
}

/* Set the dirty and/or accessed bits atomically in a linux PTE, this
 * function doesn't need to flush the hash entry
 */
static inline void hash__ptep_set_access_flags(pte_t *ptep, pte_t entry)
{
	__be64 old, tmp, val, mask;

	mask = cpu_to_be64(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_READ | _PAGE_WRITE |
			   _PAGE_EXEC | _PAGE_SOFT_DIRTY);

	val = pte_raw(entry) & mask;

	__asm__ __volatile__(
	"1:	ldarx	%0,0,%4\n\
		and.	%1,%0,%6\n\
		bne-	1b \n\
		or	%0,%3,%0\n\
		stdcx.	%0,0,%4\n\
		bne-	1b"
	:"=&r" (old), "=&r" (tmp), "=m" (*ptep)
	:"r" (val), "r" (ptep), "m" (*ptep), "r" (cpu_to_be64(H_PAGE_BUSY))
	:"cc");
}

static inline int hash__pte_same(pte_t pte_a, pte_t pte_b)
{
	return (((pte_raw(pte_a) ^ pte_raw(pte_b)) & ~cpu_to_be64(_PAGE_HPTEFLAGS)) == 0);
}

static inline int hash__pte_none(pte_t pte)
{
	return (pte_val(pte) & ~H_PTE_NONE_MASK) == 0;
}

unsigned long pte_get_hash_gslot(unsigned long vpn, unsigned long shift,
		int ssize, real_pte_t rpte, unsigned int subpg_index);

/* This low level function performs the actual PTE insertion
 * Setting the PTE depends on the MMU type and other factors. It's
 * an horrible mess that I'm not going to try to clean up now but
 * I'm keeping it in one place rather than spread around
 */
static inline void hash__set_pte_at(struct mm_struct *mm, unsigned long addr,
				  pte_t *ptep, pte_t pte, int percpu)
{
	/*
	 * Anything else just stores the PTE normally. That covers all 64-bit
	 * cases, and 32-bit non-hash with 32-bit PTEs.
	 */
	*ptep = pte;
}

#ifdef CONFIG_TRANSPARENT_HUGEPAGE
extern void hpte_do_hugepage_flush(struct mm_struct *mm, unsigned long addr,
				   pmd_t *pmdp, unsigned long old_pmd);
#else
static inline void hpte_do_hugepage_flush(struct mm_struct *mm,
					  unsigned long addr, pmd_t *pmdp,
					  unsigned long old_pmd)
{
	WARN(1, "%s called with THP disabled\n", __func__);
}
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */


int hash__map_kernel_page(unsigned long ea, unsigned long pa, pgprot_t prot);
extern int __meminit hash__vmemmap_create_mapping(unsigned long start,
					      unsigned long page_size,
					      unsigned long phys);
extern void hash__vmemmap_remove_mapping(unsigned long start,
				     unsigned long page_size);

int hash__create_section_mapping(unsigned long start, unsigned long end,
				 int nid, pgprot_t prot);
int hash__remove_section_mapping(unsigned long start, unsigned long end);

void hash__kernel_map_pages(struct page *page, int numpages, int enable);

#endif /* !__ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_BOOK3S_64_HASH_H */
