page.h 10.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 * Copyright 2010 Tilera Corporation. All Rights Reserved.
 *
 *   This program is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU General Public License
 *   as published by the Free Software Foundation, version 2.
 *
 *   This program is distributed in the hope that it will be useful, but
 *   WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
 *   NON INFRINGEMENT.  See the GNU General Public License for
 *   more details.
 */

#ifndef _ASM_TILE_PAGE_H
#define _ASM_TILE_PAGE_H

#include <linux/const.h>
19 20
#include <hv/hypervisor.h>
#include <arch/chip.h>
21 22

/* PAGE_SHIFT and HPAGE_SHIFT determine the page sizes. */
23 24 25 26 27 28 29 30 31 32 33
#if defined(CONFIG_PAGE_SIZE_16KB)
#define PAGE_SHIFT	14
#define CTX_PAGE_FLAG	HV_CTX_PG_SM_16K
#elif defined(CONFIG_PAGE_SIZE_64KB)
#define PAGE_SHIFT	16
#define CTX_PAGE_FLAG	HV_CTX_PG_SM_64K
#else
#define PAGE_SHIFT	HV_LOG2_DEFAULT_PAGE_SIZE_SMALL
#define CTX_PAGE_FLAG	0
#endif
#define HPAGE_SHIFT	HV_LOG2_DEFAULT_PAGE_SIZE_LARGE
34 35 36 37 38 39 40 41

#define PAGE_SIZE	(_AC(1, UL) << PAGE_SHIFT)
#define HPAGE_SIZE	(_AC(1, UL) << HPAGE_SHIFT)

#define PAGE_MASK	(~(PAGE_SIZE - 1))
#define HPAGE_MASK	(~(HPAGE_SIZE - 1))

/*
42 43 44
 * If the Kconfig doesn't specify, set a maximum zone order that
 * is enough so that we can create huge pages from small pages given
 * the respective sizes of the two page types.  See <linux/mmzone.h>.
45
 */
46 47
#ifndef CONFIG_FORCE_MAX_ZONEORDER
#define CONFIG_FORCE_MAX_ZONEORDER (HPAGE_SHIFT - PAGE_SHIFT + 1)
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
#endif

#ifndef __ASSEMBLY__

#include <linux/types.h>
#include <linux/string.h>

struct page;

static inline void clear_page(void *page)
{
	memset(page, 0, PAGE_SIZE);
}

static inline void copy_page(void *to, void *from)
{
	memcpy(to, from, PAGE_SIZE);
}

static inline void clear_user_page(void *page, unsigned long vaddr,
				struct page *pg)
{
	clear_page(page);
}

static inline void copy_user_page(void *to, void *from, unsigned long vaddr,
				struct page *topage)
{
	copy_page(to, from);
}

/*
 * Hypervisor page tables are made of the same basic structure.
 */

typedef HV_PTE pte_t;
typedef HV_PTE pgd_t;
typedef HV_PTE pgprot_t;

/*
 * User L2 page tables are managed as one L2 page table per page,
 * because we use the page allocator for them.  This keeps the allocation
90
 * simple, but it's also inefficient, since L2 page tables are much smaller
91 92 93 94 95 96 97
 * than pages (currently 2KB vs 64KB).  So we should revisit this.
 */
typedef struct page *pgtable_t;

/* Must be a macro since it is used to create constants. */
#define __pgprot(val) hv_pte(val)

98 99 100 101
/* Rarely-used initializers, typically with a "zero" value. */
#define __pte(x) hv_pte(x)
#define __pgd(x) hv_pte(x)

102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
static inline u64 pgprot_val(pgprot_t pgprot)
{
	return hv_pte_val(pgprot);
}

static inline u64 pte_val(pte_t pte)
{
	return hv_pte_val(pte);
}

static inline u64 pgd_val(pgd_t pgd)
{
	return hv_pte_val(pgd);
}

#ifdef __tilegx__

typedef HV_PTE pmd_t;

121 122
#define __pmd(x) hv_pte(x)

123 124 125 126 127 128 129
static inline u64 pmd_val(pmd_t pmd)
{
	return hv_pte_val(pmd);
}

#endif

C
Chris Metcalf 已提交
130 131 132 133 134
static inline __attribute_const__ int get_order(unsigned long size)
{
	return BITS_PER_LONG - __builtin_clzl((size - 1) >> PAGE_SHIFT);
}

135 136 137 138
#endif /* !__ASSEMBLY__ */

#define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT - PAGE_SHIFT)

139
#define HUGE_MAX_HSTATE		6
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176

#ifdef CONFIG_HUGETLB_PAGE
#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
#endif

/* Each memory controller has PAs distinct in their high bits. */
#define NR_PA_HIGHBIT_SHIFT (CHIP_PA_WIDTH() - CHIP_LOG_NUM_MSHIMS())
#define NR_PA_HIGHBIT_VALUES (1 << CHIP_LOG_NUM_MSHIMS())
#define __pa_to_highbits(pa) ((phys_addr_t)(pa) >> NR_PA_HIGHBIT_SHIFT)
#define __pfn_to_highbits(pfn) ((pfn) >> (NR_PA_HIGHBIT_SHIFT - PAGE_SHIFT))

#ifdef __tilegx__

/*
 * We reserve the lower half of memory for user-space programs, and the
 * upper half for system code.  We re-map all of physical memory in the
 * upper half, which takes a quarter of our VA space.  Then we have
 * the vmalloc regions.  The supervisor code lives at 0xfffffff700000000,
 * with the hypervisor above that.
 *
 * Loadable kernel modules are placed immediately after the static
 * supervisor code, with each being allocated a 256MB region of
 * address space, so we don't have to worry about the range of "jal"
 * and other branch instructions.
 *
 * For now we keep life simple and just allocate one pmd (4GB) for vmalloc.
 * Similarly, for now we don't play any struct page mapping games.
 */

#if CHIP_PA_WIDTH() + 2 > CHIP_VA_WIDTH()
# error Too much PA to map with the VA available!
#endif
#define HALF_VA_SPACE           (_AC(1, UL) << (CHIP_VA_WIDTH() - 1))

#define MEM_LOW_END		(HALF_VA_SPACE - 1)         /* low half */
#define MEM_HIGH_START		(-HALF_VA_SPACE)            /* high half */
#define PAGE_OFFSET		MEM_HIGH_START
177 178 179
#define FIXADDR_BASE		_AC(0xfffffff400000000, UL) /* 4 GB */
#define FIXADDR_TOP		_AC(0xfffffff500000000, UL) /* 4 GB */
#define _VMALLOC_START		FIXADDR_TOP
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
#define HUGE_VMAP_BASE		_AC(0xfffffff600000000, UL) /* 4 GB */
#define MEM_SV_START		_AC(0xfffffff700000000, UL) /* 256 MB */
#define MEM_SV_INTRPT		MEM_SV_START
#define MEM_MODULE_START	_AC(0xfffffff710000000, UL) /* 256 MB */
#define MEM_MODULE_END		(MEM_MODULE_START + (256*1024*1024))
#define MEM_HV_START		_AC(0xfffffff800000000, UL) /* 32 GB */

/* Highest DTLB address we will use */
#define KERNEL_HIGH_VADDR	MEM_SV_START

#else /* !__tilegx__ */

/*
 * A PAGE_OFFSET of 0xC0000000 means that the kernel has
 * a virtual address space of one gigabyte, which limits the
 * amount of physical memory you can use to about 768MB.
 * If you want more physical memory than this then see the CONFIG_HIGHMEM
 * option in the kernel configuration.
 *
199 200 201 202 203 204 205 206 207 208
 * The top 16MB chunk in the table below is unavailable to Linux.  Since
 * the kernel interrupt vectors must live at ether 0xfe000000 or 0xfd000000
 * (depending on whether the kernel is at PL2 or Pl1), we map all of the
 * bottom of RAM at this address with a huge page table entry to minimize
 * its ITLB footprint (as well as at PAGE_OFFSET).  The last architected
 * requirement is that user interrupt vectors live at 0xfc000000, so we
 * make that range of memory available to user processes.  The remaining
 * regions are sized as shown; the first four addresses use the PL 1
 * values, and after that, we show "typical" values, since the actual
 * addresses depend on kernel #defines.
209 210 211 212 213 214 215 216 217 218 219 220
 *
 * MEM_HV_INTRPT                   0xfe000000
 * MEM_SV_INTRPT (kernel code)     0xfd000000
 * MEM_USER_INTRPT (user vector)   0xfc000000
 * FIX_KMAP_xxx                    0xf8000000 (via NR_CPUS * KM_TYPE_NR)
 * PKMAP_BASE                      0xf7000000 (via LAST_PKMAP)
 * HUGE_VMAP                       0xf3000000 (via CONFIG_NR_HUGE_VMAPS)
 * VMALLOC_START                   0xf0000000 (via __VMALLOC_RESERVE)
 * mapped LOWMEM                   0xc0000000
 */

#define MEM_USER_INTRPT		_AC(0xfc000000, UL)
221
#if CONFIG_KERNEL_PL == 1
222 223
#define MEM_SV_INTRPT		_AC(0xfd000000, UL)
#define MEM_HV_INTRPT		_AC(0xfe000000, UL)
224 225 226 227 228
#else
#define MEM_GUEST_INTRPT	_AC(0xfd000000, UL)
#define MEM_SV_INTRPT		_AC(0xfe000000, UL)
#define MEM_HV_INTRPT		_AC(0xff000000, UL)
#endif
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329

#define INTRPT_SIZE		0x4000

/* Tolerate page size larger than the architecture interrupt region size. */
#if PAGE_SIZE > INTRPT_SIZE
#undef INTRPT_SIZE
#define INTRPT_SIZE PAGE_SIZE
#endif

#define KERNEL_HIGH_VADDR	MEM_USER_INTRPT
#define FIXADDR_TOP		(KERNEL_HIGH_VADDR - PAGE_SIZE)

#define PAGE_OFFSET		_AC(CONFIG_PAGE_OFFSET, UL)

/* On 32-bit architectures we mix kernel modules in with other vmaps. */
#define MEM_MODULE_START	VMALLOC_START
#define MEM_MODULE_END		VMALLOC_END

#endif /* __tilegx__ */

#ifndef __ASSEMBLY__

#ifdef CONFIG_HIGHMEM

/* Map kernel virtual addresses to page frames, in HPAGE_SIZE chunks. */
extern unsigned long pbase_map[];
extern void *vbase_map[];

static inline unsigned long kaddr_to_pfn(const volatile void *_kaddr)
{
	unsigned long kaddr = (unsigned long)_kaddr;
	return pbase_map[kaddr >> HPAGE_SHIFT] +
		((kaddr & (HPAGE_SIZE - 1)) >> PAGE_SHIFT);
}

static inline void *pfn_to_kaddr(unsigned long pfn)
{
	return vbase_map[__pfn_to_highbits(pfn)] + (pfn << PAGE_SHIFT);
}

static inline phys_addr_t virt_to_phys(const volatile void *kaddr)
{
	unsigned long pfn = kaddr_to_pfn(kaddr);
	return ((phys_addr_t)pfn << PAGE_SHIFT) +
		((unsigned long)kaddr & (PAGE_SIZE-1));
}

static inline void *phys_to_virt(phys_addr_t paddr)
{
	return pfn_to_kaddr(paddr >> PAGE_SHIFT) + (paddr & (PAGE_SIZE-1));
}

/* With HIGHMEM, we pack PAGE_OFFSET through high_memory with all valid VAs. */
static inline int virt_addr_valid(const volatile void *kaddr)
{
	extern void *high_memory;  /* copied from <linux/mm.h> */
	return ((unsigned long)kaddr >= PAGE_OFFSET && kaddr < high_memory);
}

#else /* !CONFIG_HIGHMEM */

static inline unsigned long kaddr_to_pfn(const volatile void *kaddr)
{
	return ((unsigned long)kaddr - PAGE_OFFSET) >> PAGE_SHIFT;
}

static inline void *pfn_to_kaddr(unsigned long pfn)
{
	return (void *)((pfn << PAGE_SHIFT) + PAGE_OFFSET);
}

static inline phys_addr_t virt_to_phys(const volatile void *kaddr)
{
	return (phys_addr_t)((unsigned long)kaddr - PAGE_OFFSET);
}

static inline void *phys_to_virt(phys_addr_t paddr)
{
	return (void *)((unsigned long)paddr + PAGE_OFFSET);
}

/* Check that the given address is within some mapped range of PAs. */
#define virt_addr_valid(kaddr) pfn_valid(kaddr_to_pfn(kaddr))

#endif /* !CONFIG_HIGHMEM */

/* All callers are not consistent in how they call these functions. */
#define __pa(kaddr) virt_to_phys((void *)(unsigned long)(kaddr))
#define __va(paddr) phys_to_virt((phys_addr_t)(paddr))

extern int devmem_is_allowed(unsigned long pagenr);

#ifdef CONFIG_FLATMEM
static inline int pfn_valid(unsigned long pfn)
{
	return pfn < max_mapnr;
}
#endif

/* Provide as macros since these require some other headers included. */
#define page_to_pa(page) ((phys_addr_t)(page_to_pfn(page)) << PAGE_SHIFT)
330
#define virt_to_page(kaddr) pfn_to_page(kaddr_to_pfn((void *)(kaddr)))
331 332 333 334 335 336 337 338 339 340 341 342 343
#define page_to_virt(page) pfn_to_kaddr(page_to_pfn(page))

struct mm_struct;
extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr);

#endif /* !__ASSEMBLY__ */

#define VM_DATA_DEFAULT_FLAGS \
	(VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)

#include <asm-generic/memory_model.h>

#endif /* _ASM_TILE_PAGE_H */