18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef __ASM_SH_PAGE_H 38c2ecf20Sopenharmony_ci#define __ASM_SH_PAGE_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci/* 68c2ecf20Sopenharmony_ci * Copyright (C) 1999 Niibe Yutaka 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <linux/const.h> 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci/* PAGE_SHIFT determines the page size */ 128c2ecf20Sopenharmony_ci#if defined(CONFIG_PAGE_SIZE_4KB) 138c2ecf20Sopenharmony_ci# define PAGE_SHIFT 12 148c2ecf20Sopenharmony_ci#elif defined(CONFIG_PAGE_SIZE_8KB) 158c2ecf20Sopenharmony_ci# define PAGE_SHIFT 13 168c2ecf20Sopenharmony_ci#elif defined(CONFIG_PAGE_SIZE_16KB) 178c2ecf20Sopenharmony_ci# define PAGE_SHIFT 14 188c2ecf20Sopenharmony_ci#elif defined(CONFIG_PAGE_SIZE_64KB) 198c2ecf20Sopenharmony_ci# define PAGE_SHIFT 16 208c2ecf20Sopenharmony_ci#else 218c2ecf20Sopenharmony_ci# error "Bogus kernel page size?" 228c2ecf20Sopenharmony_ci#endif 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) 258c2ecf20Sopenharmony_ci#define PAGE_MASK (~(PAGE_SIZE-1)) 268c2ecf20Sopenharmony_ci#define PTE_MASK PAGE_MASK 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci#if defined(CONFIG_HUGETLB_PAGE_SIZE_64K) 298c2ecf20Sopenharmony_ci#define HPAGE_SHIFT 16 308c2ecf20Sopenharmony_ci#elif defined(CONFIG_HUGETLB_PAGE_SIZE_256K) 318c2ecf20Sopenharmony_ci#define HPAGE_SHIFT 18 328c2ecf20Sopenharmony_ci#elif defined(CONFIG_HUGETLB_PAGE_SIZE_1MB) 338c2ecf20Sopenharmony_ci#define HPAGE_SHIFT 20 348c2ecf20Sopenharmony_ci#elif defined(CONFIG_HUGETLB_PAGE_SIZE_4MB) 358c2ecf20Sopenharmony_ci#define HPAGE_SHIFT 22 368c2ecf20Sopenharmony_ci#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64MB) 378c2ecf20Sopenharmony_ci#define HPAGE_SHIFT 26 388c2ecf20Sopenharmony_ci#endif 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci#ifdef CONFIG_HUGETLB_PAGE 418c2ecf20Sopenharmony_ci#define HPAGE_SIZE (1UL << HPAGE_SHIFT) 428c2ecf20Sopenharmony_ci#define HPAGE_MASK (~(HPAGE_SIZE-1)) 438c2ecf20Sopenharmony_ci#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT-PAGE_SHIFT) 448c2ecf20Sopenharmony_ci#endif 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 478c2ecf20Sopenharmony_ci#include <asm/uncached.h> 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ciextern unsigned long shm_align_mask; 508c2ecf20Sopenharmony_ciextern unsigned long max_low_pfn, min_low_pfn; 518c2ecf20Sopenharmony_ciextern unsigned long memory_start, memory_end, memory_limit; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_cistatic inline unsigned long 548c2ecf20Sopenharmony_cipages_do_alias(unsigned long addr1, unsigned long addr2) 558c2ecf20Sopenharmony_ci{ 568c2ecf20Sopenharmony_ci return (addr1 ^ addr2) & shm_align_mask; 578c2ecf20Sopenharmony_ci} 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) 608c2ecf20Sopenharmony_ciextern void copy_page(void *to, void *from); 618c2ecf20Sopenharmony_ci#define copy_user_page(to, from, vaddr, pg) __copy_user(to, from, PAGE_SIZE) 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_cistruct page; 648c2ecf20Sopenharmony_cistruct vm_area_struct; 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ciextern void copy_user_highpage(struct page *to, struct page *from, 678c2ecf20Sopenharmony_ci unsigned long vaddr, struct vm_area_struct *vma); 688c2ecf20Sopenharmony_ci#define __HAVE_ARCH_COPY_USER_HIGHPAGE 698c2ecf20Sopenharmony_ciextern void clear_user_highpage(struct page *page, unsigned long vaddr); 708c2ecf20Sopenharmony_ci#define clear_user_highpage clear_user_highpage 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci/* 738c2ecf20Sopenharmony_ci * These are used to make use of C type-checking.. 748c2ecf20Sopenharmony_ci */ 758c2ecf20Sopenharmony_ci#ifdef CONFIG_X2TLB 768c2ecf20Sopenharmony_citypedef struct { unsigned long pte_low, pte_high; } pte_t; 778c2ecf20Sopenharmony_citypedef struct { unsigned long long pgprot; } pgprot_t; 788c2ecf20Sopenharmony_citypedef struct { unsigned long long pgd; } pgd_t; 798c2ecf20Sopenharmony_ci#define pte_val(x) \ 808c2ecf20Sopenharmony_ci ((x).pte_low | ((unsigned long long)(x).pte_high << 32)) 818c2ecf20Sopenharmony_ci#define __pte(x) \ 828c2ecf20Sopenharmony_ci ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; }) 838c2ecf20Sopenharmony_ci#else 848c2ecf20Sopenharmony_citypedef struct { unsigned long pte_low; } pte_t; 858c2ecf20Sopenharmony_citypedef struct { unsigned long pgprot; } pgprot_t; 868c2ecf20Sopenharmony_citypedef struct { unsigned long pgd; } pgd_t; 878c2ecf20Sopenharmony_ci#define pte_val(x) ((x).pte_low) 888c2ecf20Sopenharmony_ci#define __pte(x) ((pte_t) { (x) } ) 898c2ecf20Sopenharmony_ci#endif 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci#define pgd_val(x) ((x).pgd) 928c2ecf20Sopenharmony_ci#define pgprot_val(x) ((x).pgprot) 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci#define __pgd(x) ((pgd_t) { (x) } ) 958c2ecf20Sopenharmony_ci#define __pgprot(x) ((pgprot_t) { (x) } ) 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_citypedef struct page *pgtable_t; 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci#define pte_pgprot(x) __pgprot(pte_val(x) & PTE_FLAGS_MASK) 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci#endif /* !__ASSEMBLY__ */ 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci/* 1048c2ecf20Sopenharmony_ci * __MEMORY_START and SIZE are the physical addresses and size of RAM. 1058c2ecf20Sopenharmony_ci */ 1068c2ecf20Sopenharmony_ci#define __MEMORY_START CONFIG_MEMORY_START 1078c2ecf20Sopenharmony_ci#define __MEMORY_SIZE CONFIG_MEMORY_SIZE 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci/* 1108c2ecf20Sopenharmony_ci * PHYSICAL_OFFSET is the offset in physical memory where the base 1118c2ecf20Sopenharmony_ci * of the kernel is loaded. 1128c2ecf20Sopenharmony_ci */ 1138c2ecf20Sopenharmony_ci#ifdef CONFIG_PHYSICAL_START 1148c2ecf20Sopenharmony_ci#define PHYSICAL_OFFSET (CONFIG_PHYSICAL_START - __MEMORY_START) 1158c2ecf20Sopenharmony_ci#else 1168c2ecf20Sopenharmony_ci#define PHYSICAL_OFFSET 0 1178c2ecf20Sopenharmony_ci#endif 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci/* 1208c2ecf20Sopenharmony_ci * PAGE_OFFSET is the virtual address of the start of kernel address 1218c2ecf20Sopenharmony_ci * space. 1228c2ecf20Sopenharmony_ci */ 1238c2ecf20Sopenharmony_ci#define PAGE_OFFSET CONFIG_PAGE_OFFSET 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci/* 1268c2ecf20Sopenharmony_ci * Virtual to physical RAM address translation. 1278c2ecf20Sopenharmony_ci * 1288c2ecf20Sopenharmony_ci * In 29 bit mode, the physical offset of RAM from address 0 is visible in 1298c2ecf20Sopenharmony_ci * the kernel virtual address space, and thus we don't have to take 1308c2ecf20Sopenharmony_ci * this into account when translating. However in 32 bit mode this offset 1318c2ecf20Sopenharmony_ci * is not visible (it is part of the PMB mapping) and so needs to be 1328c2ecf20Sopenharmony_ci * added or subtracted as required. 1338c2ecf20Sopenharmony_ci */ 1348c2ecf20Sopenharmony_ci#ifdef CONFIG_PMB 1358c2ecf20Sopenharmony_ci#define ___pa(x) ((x)-PAGE_OFFSET+__MEMORY_START) 1368c2ecf20Sopenharmony_ci#define ___va(x) ((x)+PAGE_OFFSET-__MEMORY_START) 1378c2ecf20Sopenharmony_ci#else 1388c2ecf20Sopenharmony_ci#define ___pa(x) ((x)-PAGE_OFFSET) 1398c2ecf20Sopenharmony_ci#define ___va(x) ((x)+PAGE_OFFSET) 1408c2ecf20Sopenharmony_ci#endif 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 1438c2ecf20Sopenharmony_ci#define __pa(x) ___pa((unsigned long)x) 1448c2ecf20Sopenharmony_ci#define __va(x) (void *)___va((unsigned long)x) 1458c2ecf20Sopenharmony_ci#endif /* !__ASSEMBLY__ */ 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci#ifdef CONFIG_UNCACHED_MAPPING 1488c2ecf20Sopenharmony_ci#if defined(CONFIG_29BIT) 1498c2ecf20Sopenharmony_ci#define UNCAC_ADDR(addr) P2SEGADDR(addr) 1508c2ecf20Sopenharmony_ci#define CAC_ADDR(addr) P1SEGADDR(addr) 1518c2ecf20Sopenharmony_ci#else 1528c2ecf20Sopenharmony_ci#define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + uncached_start) 1538c2ecf20Sopenharmony_ci#define CAC_ADDR(addr) ((addr) - uncached_start + PAGE_OFFSET) 1548c2ecf20Sopenharmony_ci#endif 1558c2ecf20Sopenharmony_ci#else 1568c2ecf20Sopenharmony_ci#define UNCAC_ADDR(addr) ((addr)) 1578c2ecf20Sopenharmony_ci#define CAC_ADDR(addr) ((addr)) 1588c2ecf20Sopenharmony_ci#endif 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) 1618c2ecf20Sopenharmony_ci#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci/* 1648c2ecf20Sopenharmony_ci * PFN = physical frame number (ie PFN 0 == physical address 0) 1658c2ecf20Sopenharmony_ci * PFN_START is the PFN of the first page of RAM. By defining this we 1668c2ecf20Sopenharmony_ci * don't have struct page entries for the portion of address space 1678c2ecf20Sopenharmony_ci * between physical address 0 and the start of RAM. 1688c2ecf20Sopenharmony_ci */ 1698c2ecf20Sopenharmony_ci#define PFN_START (__MEMORY_START >> PAGE_SHIFT) 1708c2ecf20Sopenharmony_ci#define ARCH_PFN_OFFSET (PFN_START) 1718c2ecf20Sopenharmony_ci#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) 1728c2ecf20Sopenharmony_ci#ifdef CONFIG_FLATMEM 1738c2ecf20Sopenharmony_ci#define pfn_valid(pfn) ((pfn) >= min_low_pfn && (pfn) < max_low_pfn) 1748c2ecf20Sopenharmony_ci#endif 1758c2ecf20Sopenharmony_ci#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci#include <asm-generic/memory_model.h> 1788c2ecf20Sopenharmony_ci#include <asm-generic/getorder.h> 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci/* 1818c2ecf20Sopenharmony_ci * Some drivers need to perform DMA into kmalloc'ed buffers 1828c2ecf20Sopenharmony_ci * and so we have to increase the kmalloc minalign for this. 1838c2ecf20Sopenharmony_ci */ 1848c2ecf20Sopenharmony_ci#define ARCH_DMA_MINALIGN L1_CACHE_BYTES 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci#endif /* __ASM_SH_PAGE_H */ 187