page.h 9.9 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

#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))

41 42 43 44 45 46
/*
 * We do define AT_SYSINFO_EHDR to support vDSO,
 * but don't use the gate mechanism.
 */
#define __HAVE_ARCH_GATE_AREA		1

47
/*
48 49 50
 * 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>.
51
 */
52 53
#ifndef CONFIG_FORCE_MAX_ZONEORDER
#define CONFIG_FORCE_MAX_ZONEORDER (HPAGE_SHIFT - PAGE_SHIFT + 1)
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 90 91 92 93 94 95
#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
96
 * simple, but it's also inefficient, since L2 page tables are much smaller
97 98 99 100 101 102 103
 * 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)

104 105 106 107
/* Rarely-used initializers, typically with a "zero" value. */
#define __pte(x) hv_pte(x)
#define __pgd(x) hv_pte(x)

108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
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;

127 128
#define __pmd(x) hv_pte(x)

129 130 131 132 133 134 135
static inline u64 pmd_val(pmd_t pmd)
{
	return hv_pte_val(pmd);
}

#endif

C
Chris Metcalf 已提交
136 137 138 139 140
static inline __attribute_const__ int get_order(unsigned long size)
{
	return BITS_PER_LONG - __builtin_clzl((size - 1) >> PAGE_SHIFT);
}

141 142 143 144
#endif /* !__ASSEMBLY__ */

#define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT - PAGE_SHIFT)

145
#define HUGE_MAX_HSTATE		6
146 147 148 149 150

#ifdef CONFIG_HUGETLB_PAGE
#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
#endif

151 152 153 154
/* Allow overriding how much VA or PA the kernel will use. */
#define MAX_PA_WIDTH CHIP_PA_WIDTH()
#define MAX_VA_WIDTH CHIP_VA_WIDTH()

155
/* Each memory controller has PAs distinct in their high bits. */
156
#define NR_PA_HIGHBIT_SHIFT (MAX_PA_WIDTH - CHIP_LOG_NUM_MSHIMS())
157 158 159 160 161 162 163 164 165 166
#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
167
 * the vmalloc regions.  The supervisor code lives at the highest address,
168 169 170 171 172 173 174 175 176 177 178
 * 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.
 */

179
#if MAX_PA_WIDTH + 2 > MAX_VA_WIDTH
180 181 182
# error Too much PA to map with the VA available!
#endif

183 184
#define PAGE_OFFSET		(-(_AC(1, UL) << (MAX_VA_WIDTH - 1)))
#define KERNEL_HIGH_VADDR	_AC(0xfffffff800000000, UL)  /* high 32GB */
C
Chris Metcalf 已提交
185 186
#define FIXADDR_BASE		(KERNEL_HIGH_VADDR - 0x300000000) /* 4 GB */
#define FIXADDR_TOP		(KERNEL_HIGH_VADDR - 0x200000000) /* 4 GB */
187
#define _VMALLOC_START		FIXADDR_TOP
188 189
#define MEM_SV_START		(KERNEL_HIGH_VADDR - 0x100000000) /* 256 MB */
#define MEM_MODULE_START	(MEM_SV_START + (256*1024*1024)) /* 256 MB */
190 191 192 193 194 195 196 197 198 199 200
#define MEM_MODULE_END		(MEM_MODULE_START + (256*1024*1024))

#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.
 *
201 202 203 204 205 206 207 208 209 210
 * 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.
211
 *
212 213
 * MEM_HV_START                    0xfe000000
 * MEM_SV_START  (kernel code)     0xfd000000
214
 * MEM_USER_INTRPT (user vector)   0xfc000000
215 216 217
 * FIX_KMAP_xxx                    0xfa000000 (via NR_CPUS * KM_TYPE_NR)
 * PKMAP_BASE                      0xf9000000 (via LAST_PKMAP)
 * VMALLOC_START                   0xf7000000 (via VMALLOC_RESERVE)
218 219 220 221
 * mapped LOWMEM                   0xc0000000
 */

#define MEM_USER_INTRPT		_AC(0xfc000000, UL)
222 223
#define MEM_SV_START		_AC(0xfd000000, UL)
#define MEM_HV_START		_AC(0xfe000000, UL)
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243

#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__ */

244
#if !defined(__ASSEMBLY__) && !defined(VDSO_BUILD)
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

#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)
325
#define virt_to_page(kaddr) pfn_to_page(kaddr_to_pfn((void *)(kaddr)))
326 327 328 329
#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);
330
extern pte_t *virt_to_kpte(unsigned long kaddr);
331 332 333 334 335 336 337 338 339

#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 */