162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef __ASM_SH_PAGE_H
362306a36Sopenharmony_ci#define __ASM_SH_PAGE_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci/*
662306a36Sopenharmony_ci * Copyright (C) 1999  Niibe Yutaka
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/const.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci/* PAGE_SHIFT determines the page size */
1262306a36Sopenharmony_ci#if defined(CONFIG_PAGE_SIZE_4KB)
1362306a36Sopenharmony_ci# define PAGE_SHIFT	12
1462306a36Sopenharmony_ci#elif defined(CONFIG_PAGE_SIZE_8KB)
1562306a36Sopenharmony_ci# define PAGE_SHIFT	13
1662306a36Sopenharmony_ci#elif defined(CONFIG_PAGE_SIZE_16KB)
1762306a36Sopenharmony_ci# define PAGE_SHIFT	14
1862306a36Sopenharmony_ci#elif defined(CONFIG_PAGE_SIZE_64KB)
1962306a36Sopenharmony_ci# define PAGE_SHIFT	16
2062306a36Sopenharmony_ci#else
2162306a36Sopenharmony_ci# error "Bogus kernel page size?"
2262306a36Sopenharmony_ci#endif
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci#define PAGE_SIZE	(_AC(1, UL) << PAGE_SHIFT)
2562306a36Sopenharmony_ci#define PAGE_MASK	(~(PAGE_SIZE-1))
2662306a36Sopenharmony_ci#define PTE_MASK	PAGE_MASK
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci#if defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
2962306a36Sopenharmony_ci#define HPAGE_SHIFT	16
3062306a36Sopenharmony_ci#elif defined(CONFIG_HUGETLB_PAGE_SIZE_256K)
3162306a36Sopenharmony_ci#define HPAGE_SHIFT	18
3262306a36Sopenharmony_ci#elif defined(CONFIG_HUGETLB_PAGE_SIZE_1MB)
3362306a36Sopenharmony_ci#define HPAGE_SHIFT	20
3462306a36Sopenharmony_ci#elif defined(CONFIG_HUGETLB_PAGE_SIZE_4MB)
3562306a36Sopenharmony_ci#define HPAGE_SHIFT	22
3662306a36Sopenharmony_ci#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64MB)
3762306a36Sopenharmony_ci#define HPAGE_SHIFT	26
3862306a36Sopenharmony_ci#endif
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci#ifdef CONFIG_HUGETLB_PAGE
4162306a36Sopenharmony_ci#define HPAGE_SIZE		(1UL << HPAGE_SHIFT)
4262306a36Sopenharmony_ci#define HPAGE_MASK		(~(HPAGE_SIZE-1))
4362306a36Sopenharmony_ci#define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT-PAGE_SHIFT)
4462306a36Sopenharmony_ci#endif
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci#ifndef __ASSEMBLY__
4762306a36Sopenharmony_ci#include <asm/uncached.h>
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ciextern unsigned long shm_align_mask;
5062306a36Sopenharmony_ciextern unsigned long max_low_pfn, min_low_pfn;
5162306a36Sopenharmony_ciextern unsigned long memory_start, memory_end, memory_limit;
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_cistatic inline unsigned long
5462306a36Sopenharmony_cipages_do_alias(unsigned long addr1, unsigned long addr2)
5562306a36Sopenharmony_ci{
5662306a36Sopenharmony_ci	return (addr1 ^ addr2) & shm_align_mask;
5762306a36Sopenharmony_ci}
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci#define clear_page(page)	memset((void *)(page), 0, PAGE_SIZE)
6062306a36Sopenharmony_ciextern void copy_page(void *to, void *from);
6162306a36Sopenharmony_ci#define copy_user_page(to, from, vaddr, pg)  __copy_user(to, from, PAGE_SIZE)
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_cistruct page;
6462306a36Sopenharmony_cistruct vm_area_struct;
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ciextern void copy_user_highpage(struct page *to, struct page *from,
6762306a36Sopenharmony_ci			       unsigned long vaddr, struct vm_area_struct *vma);
6862306a36Sopenharmony_ci#define __HAVE_ARCH_COPY_USER_HIGHPAGE
6962306a36Sopenharmony_ciextern void clear_user_highpage(struct page *page, unsigned long vaddr);
7062306a36Sopenharmony_ci#define clear_user_highpage	clear_user_highpage
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci/*
7362306a36Sopenharmony_ci * These are used to make use of C type-checking..
7462306a36Sopenharmony_ci */
7562306a36Sopenharmony_ci#ifdef CONFIG_X2TLB
7662306a36Sopenharmony_citypedef struct { unsigned long pte_low, pte_high; } pte_t;
7762306a36Sopenharmony_citypedef struct { unsigned long long pgprot; } pgprot_t;
7862306a36Sopenharmony_citypedef struct { unsigned long long pgd; } pgd_t;
7962306a36Sopenharmony_ci#define pte_val(x) \
8062306a36Sopenharmony_ci	((x).pte_low | ((unsigned long long)(x).pte_high << 32))
8162306a36Sopenharmony_ci#define __pte(x) \
8262306a36Sopenharmony_ci	({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
8362306a36Sopenharmony_ci#else
8462306a36Sopenharmony_citypedef struct { unsigned long pte_low; } pte_t;
8562306a36Sopenharmony_citypedef struct { unsigned long pgprot; } pgprot_t;
8662306a36Sopenharmony_citypedef struct { unsigned long pgd; } pgd_t;
8762306a36Sopenharmony_ci#define pte_val(x)	((x).pte_low)
8862306a36Sopenharmony_ci#define __pte(x)	((pte_t) { (x) } )
8962306a36Sopenharmony_ci#endif
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci#define pgd_val(x)	((x).pgd)
9262306a36Sopenharmony_ci#define pgprot_val(x)	((x).pgprot)
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci#define __pgd(x) ((pgd_t) { (x) } )
9562306a36Sopenharmony_ci#define __pgprot(x)	((pgprot_t) { (x) } )
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_citypedef struct page *pgtable_t;
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci#define pte_pgprot(x) __pgprot(pte_val(x) & PTE_FLAGS_MASK)
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci#endif /* !__ASSEMBLY__ */
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci/*
10462306a36Sopenharmony_ci * __MEMORY_START and SIZE are the physical addresses and size of RAM.
10562306a36Sopenharmony_ci */
10662306a36Sopenharmony_ci#define __MEMORY_START		CONFIG_MEMORY_START
10762306a36Sopenharmony_ci#define __MEMORY_SIZE		CONFIG_MEMORY_SIZE
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci/*
11062306a36Sopenharmony_ci * PHYSICAL_OFFSET is the offset in physical memory where the base
11162306a36Sopenharmony_ci * of the kernel is loaded.
11262306a36Sopenharmony_ci */
11362306a36Sopenharmony_ci#ifdef CONFIG_PHYSICAL_START
11462306a36Sopenharmony_ci#define PHYSICAL_OFFSET (CONFIG_PHYSICAL_START - __MEMORY_START)
11562306a36Sopenharmony_ci#else
11662306a36Sopenharmony_ci#define PHYSICAL_OFFSET 0
11762306a36Sopenharmony_ci#endif
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci/*
12062306a36Sopenharmony_ci * PAGE_OFFSET is the virtual address of the start of kernel address
12162306a36Sopenharmony_ci * space.
12262306a36Sopenharmony_ci */
12362306a36Sopenharmony_ci#define PAGE_OFFSET		CONFIG_PAGE_OFFSET
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci/*
12662306a36Sopenharmony_ci * Virtual to physical RAM address translation.
12762306a36Sopenharmony_ci *
12862306a36Sopenharmony_ci * In 29 bit mode, the physical offset of RAM from address 0 is visible in
12962306a36Sopenharmony_ci * the kernel virtual address space, and thus we don't have to take
13062306a36Sopenharmony_ci * this into account when translating. However in 32 bit mode this offset
13162306a36Sopenharmony_ci * is not visible (it is part of the PMB mapping) and so needs to be
13262306a36Sopenharmony_ci * added or subtracted as required.
13362306a36Sopenharmony_ci */
13462306a36Sopenharmony_ci#ifdef CONFIG_PMB
13562306a36Sopenharmony_ci#define ___pa(x)	((x)-PAGE_OFFSET+__MEMORY_START)
13662306a36Sopenharmony_ci#define ___va(x)	((x)+PAGE_OFFSET-__MEMORY_START)
13762306a36Sopenharmony_ci#else
13862306a36Sopenharmony_ci#define ___pa(x)	((x)-PAGE_OFFSET)
13962306a36Sopenharmony_ci#define ___va(x)	((x)+PAGE_OFFSET)
14062306a36Sopenharmony_ci#endif
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci#ifndef __ASSEMBLY__
14362306a36Sopenharmony_ci#define __pa(x)		___pa((unsigned long)x)
14462306a36Sopenharmony_ci#define __va(x)		(void *)___va((unsigned long)x)
14562306a36Sopenharmony_ci#endif /* !__ASSEMBLY__ */
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci#ifdef CONFIG_UNCACHED_MAPPING
14862306a36Sopenharmony_ci#if defined(CONFIG_29BIT)
14962306a36Sopenharmony_ci#define UNCAC_ADDR(addr)	P2SEGADDR(addr)
15062306a36Sopenharmony_ci#define CAC_ADDR(addr)		P1SEGADDR(addr)
15162306a36Sopenharmony_ci#else
15262306a36Sopenharmony_ci#define UNCAC_ADDR(addr)	((addr) - PAGE_OFFSET + uncached_start)
15362306a36Sopenharmony_ci#define CAC_ADDR(addr)		((addr) - uncached_start + PAGE_OFFSET)
15462306a36Sopenharmony_ci#endif
15562306a36Sopenharmony_ci#else
15662306a36Sopenharmony_ci#define UNCAC_ADDR(addr)	((addr))
15762306a36Sopenharmony_ci#define CAC_ADDR(addr)		((addr))
15862306a36Sopenharmony_ci#endif
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci#define pfn_to_kaddr(pfn)	__va((pfn) << PAGE_SHIFT)
16162306a36Sopenharmony_ci#define page_to_phys(page)	(page_to_pfn(page) << PAGE_SHIFT)
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci/*
16462306a36Sopenharmony_ci * PFN = physical frame number (ie PFN 0 == physical address 0)
16562306a36Sopenharmony_ci * PFN_START is the PFN of the first page of RAM. By defining this we
16662306a36Sopenharmony_ci * don't have struct page entries for the portion of address space
16762306a36Sopenharmony_ci * between physical address 0 and the start of RAM.
16862306a36Sopenharmony_ci */
16962306a36Sopenharmony_ci#define PFN_START		(__MEMORY_START >> PAGE_SHIFT)
17062306a36Sopenharmony_ci#define ARCH_PFN_OFFSET		(PFN_START)
17162306a36Sopenharmony_ci#define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
17262306a36Sopenharmony_ci#define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci#include <asm-generic/memory_model.h>
17562306a36Sopenharmony_ci#include <asm-generic/getorder.h>
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci#endif /* __ASM_SH_PAGE_H */
178