1/* 2 * Page management definitions for the Hexagon architecture 3 * 4 * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 and 8 * only version 2 as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 * 02110-1301, USA. 19 */ 20 21#ifndef _ASM_PAGE_H 22#define _ASM_PAGE_H 23 24#include <linux/const.h> 25 26/* This is probably not the most graceful way to handle this. */ 27 28#ifdef CONFIG_PAGE_SIZE_4KB 29#define PAGE_SHIFT 12 30#define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_4KB 31#endif 32 33#ifdef CONFIG_PAGE_SIZE_16KB 34#define PAGE_SHIFT 14 35#define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_16KB 36#endif 37 38#ifdef CONFIG_PAGE_SIZE_64KB 39#define PAGE_SHIFT 16 40#define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_64KB 41#endif 42 43#ifdef CONFIG_PAGE_SIZE_256KB 44#define PAGE_SHIFT 18 45#define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_256KB 46#endif 47 48#ifdef CONFIG_PAGE_SIZE_1MB 49#define PAGE_SHIFT 20 50#define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_1MB 51#endif 52 53/* 54 * These should be defined in hugetlb.h, but apparently not. 55 * "Huge" for us should be 4MB or 16MB, which are both represented 56 * in L1 PTE's. Right now, it's set up for 4MB. 57 */ 58#ifdef CONFIG_HUGETLB_PAGE 59#define HPAGE_SHIFT 22 60#define HPAGE_SIZE (1UL << HPAGE_SHIFT) 61#define HPAGE_MASK (~(HPAGE_SIZE-1)) 62#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT-PAGE_SHIFT) 63#define HVM_HUGEPAGE_SIZE 0x5 64#endif 65 66#define PAGE_SIZE (1UL << PAGE_SHIFT) 67#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1)) 68 69#ifdef __KERNEL__ 70#ifndef __ASSEMBLY__ 71 72/* 73 * This is for PFN_DOWN, which mm.h needs. Seems the right place to pull it in. 74 */ 75#include <linux/pfn.h> 76 77/* 78 * We implement a two-level architecture-specific page table structure. 79 * Null intermediate page table level (pmd, pud) definitions will come from 80 * asm-generic/pagetable-nopmd.h and asm-generic/pagetable-nopud.h 81 */ 82typedef struct { unsigned long pte; } pte_t; 83typedef struct { unsigned long pgd; } pgd_t; 84typedef struct { unsigned long pgprot; } pgprot_t; 85typedef struct page *pgtable_t; 86 87#define pte_val(x) ((x).pte) 88#define pgd_val(x) ((x).pgd) 89#define pgprot_val(x) ((x).pgprot) 90#define __pte(x) ((pte_t) { (x) }) 91#define __pgd(x) ((pgd_t) { (x) }) 92#define __pgprot(x) ((pgprot_t) { (x) }) 93 94/* 95 * We need a __pa and a __va routine for kernel space. 96 * MIPS says they're only used during mem_init. 97 * also, check if we need a PHYS_OFFSET. 98 */ 99#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET + PHYS_OFFSET) 100#define __va(x) ((void *)((unsigned long)(x) - PHYS_OFFSET + PAGE_OFFSET)) 101 102/* The "page frame" descriptor is defined in linux/mm.h */ 103struct page; 104 105/* Returns page frame descriptor for virtual address. */ 106#define virt_to_page(kaddr) pfn_to_page(PFN_DOWN(__pa(kaddr))) 107 108/* Default vm area behavior is non-executable. */ 109#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | \ 110 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) 111 112#define pfn_valid(pfn) ((pfn) < max_mapnr) 113#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) 114 115/* Need to not use a define for linesize; may move this to another file. */ 116static inline void clear_page(void *page) 117{ 118 /* This can only be done on pages with L1 WB cache */ 119 asm volatile( 120 " loop0(1f,%1);\n" 121 "1: { dczeroa(%0);\n" 122 " %0 = add(%0,#32); }:endloop0\n" 123 : "+r" (page) 124 : "r" (PAGE_SIZE/32) 125 : "lc0", "sa0", "memory" 126 ); 127} 128 129#define copy_page(to, from) memcpy((to), (from), PAGE_SIZE) 130 131/* 132 * Under assumption that kernel always "sees" user map... 133 */ 134#define clear_user_page(page, vaddr, pg) clear_page(page) 135#define copy_user_page(to, from, vaddr, pg) copy_page(to, from) 136 137/* 138 * page_to_phys - convert page to physical address 139 * @page - pointer to page entry in mem_map 140 */ 141#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) 142 143#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) 144#define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT) 145 146#define page_to_virt(page) __va(page_to_phys(page)) 147 148/* 149 * For port to Hexagon Virtual Machine, MAYBE we check for attempts 150 * to reference reserved HVM space, but in any case, the VM will be 151 * protected. 152 */ 153#define kern_addr_valid(addr) (1) 154 155#include <asm/mem-layout.h> 156#include <asm-generic/memory_model.h> 157/* XXX Todo: implement assembly-optimized version of getorder. */ 158#include <asm-generic/getorder.h> 159 160#endif /* ifdef __ASSEMBLY__ */ 161#endif /* ifdef __KERNEL__ */ 162 163#endif 164