117f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas/*
217f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas *  arch/arm/include/asm/pgtable-2level.h
317f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas *
417f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas *  Copyright (C) 1995-2002 Russell King
517f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas *
617f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * This program is free software; you can redistribute it and/or modify
717f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * it under the terms of the GNU General Public License version 2 as
817f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * published by the Free Software Foundation.
917f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas */
1017f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#ifndef _ASM_PGTABLE_2LEVEL_H
1117f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define _ASM_PGTABLE_2LEVEL_H
1217f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas
1317f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas/*
1417f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * Hardware-wise, we have a two level page table structure, where the first
1517f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * level has 4096 entries, and the second level has 256 entries.  Each entry
1617f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * is one 32-bit word.  Most of the bits in the second level entry are used
1717f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * by hardware, and there aren't any "accessed" and "dirty" bits.
1817f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas *
1917f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * Linux on the other hand has a three level page table structure, which can
2017f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * be wrapped to fit a two level page table structure easily - using the PGD
2117f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * and PTE only.  However, Linux also expects one "PTE" table per page, and
2217f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * at least a "dirty" bit.
2317f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas *
2417f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * Therefore, we tweak the implementation slightly - we tell Linux that we
2517f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * have 2048 entries in the first level, each of which is 8 bytes (iow, two
2617f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * hardware pointers to the second level.)  The second level contains two
2717f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * hardware PTE tables arranged contiguously, preceded by Linux versions
2817f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * which contain the state information Linux needs.  We, therefore, end up
2917f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * with 512 entries in the "PTE" level.
3017f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas *
3117f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * This leads to the page tables having the following layout:
3217f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas *
3317f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas *    pgd             pte
3417f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * |        |
3517f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * +--------+
3617f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * |        |       +------------+ +0
3717f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * +- - - - +       | Linux pt 0 |
3817f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * |        |       +------------+ +1024
3917f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * +--------+ +0    | Linux pt 1 |
4017f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * |        |-----> +------------+ +2048
4117f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * +- - - - + +4    |  h/w pt 0  |
4217f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * |        |-----> +------------+ +3072
4317f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * +--------+ +8    |  h/w pt 1  |
4417f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * |        |       +------------+ +4096
4517f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas *
4617f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * See L_PTE_xxx below for definitions of bits in the "Linux pt", and
4717f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * PTE_xxx for definitions of bits appearing in the "h/w pt".
4817f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas *
4917f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * PMD_xxx definitions refer to bits in the first level page table.
5017f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas *
5117f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * The "dirty" bit is emulated by only granting hardware write permission
5217f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * iff the page is marked "writable" and "dirty" in the Linux PTE.  This
5317f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * means that a write to a clean page will cause a permission fault, and
5417f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * the Linux MM layer will mark the page dirty via handle_pte_fault().
5517f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * For the hardware to notice the permission change, the TLB entry must
5617f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * be flushed, and ptep_set_access_flags() does that for us.
5717f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas *
5817f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * The "accessed" or "young" bit is emulated by a similar method; we only
5917f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * allow accesses to the page if the "young" bit is set.  Accesses to the
6017f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * page will cause a fault, and handle_pte_fault() will set the young bit
6117f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * for us as long as the page is marked present in the corresponding Linux
6217f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * PTE entry.  Again, ptep_set_access_flags() will ensure that the TLB is
6317f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * up to date.
6417f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas *
6517f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * However, when the "young" bit is cleared, we deny access to the page
6617f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * by clearing the hardware PTE.  Currently Linux does not flush the TLB
6717f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * for us in this case, which means the TLB will retain the transation
6817f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * until either the TLB entry is evicted under pressure, or a context
6917f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * switch which changes the user space mapping occurs.
7017f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas */
7117f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define PTRS_PER_PTE		512
7217f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define PTRS_PER_PMD		1
7317f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define PTRS_PER_PGD		2048
7417f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas
7517f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define PTE_HWTABLE_PTRS	(PTRS_PER_PTE)
7617f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define PTE_HWTABLE_OFF		(PTE_HWTABLE_PTRS * sizeof(pte_t))
7717f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define PTE_HWTABLE_SIZE	(PTRS_PER_PTE * sizeof(u32))
7817f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas
7917f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas/*
8017f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * PMD_SHIFT determines the size of the area a second-level page table can map
8117f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * PGDIR_SHIFT determines what a third-level page table entry can map
8217f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas */
8317f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define PMD_SHIFT		21
8417f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define PGDIR_SHIFT		21
8517f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas
8617f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define PMD_SIZE		(1UL << PMD_SHIFT)
8717f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define PMD_MASK		(~(PMD_SIZE-1))
8817f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define PGDIR_SIZE		(1UL << PGDIR_SHIFT)
8917f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define PGDIR_MASK		(~(PGDIR_SIZE-1))
9017f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas
9117f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas/*
9217f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * section address mask and size definitions.
9317f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas */
9417f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define SECTION_SHIFT		20
9517f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define SECTION_SIZE		(1UL << SECTION_SHIFT)
9617f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define SECTION_MASK		(~(SECTION_SIZE-1))
9717f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas
9817f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas/*
9917f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * ARMv6 supersection address mask and size definitions.
10017f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas */
10117f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define SUPERSECTION_SHIFT	24
10217f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define SUPERSECTION_SIZE	(1UL << SUPERSECTION_SHIFT)
10317f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define SUPERSECTION_MASK	(~(SUPERSECTION_SIZE-1))
10417f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas
10517f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define USER_PTRS_PER_PGD	(TASK_SIZE / PGDIR_SIZE)
10617f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas
10717f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas/*
10817f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * "Linux" PTE definitions.
10917f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas *
11017f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * We keep two sets of PTEs - the hardware and the linux version.
11117f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * This allows greater flexibility in the way we map the Linux bits
11217f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * onto the hardware tables, and allows us to have YOUNG and DIRTY
11317f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * bits.
11417f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas *
11517f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * The PTE table pointer refers to the hardware entries; the "Linux"
11617f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * entries are stored 1024 bytes below.
11717f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas */
11817f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define L_PTE_PRESENT		(_AT(pteval_t, 1) << 0)
11917f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define L_PTE_YOUNG		(_AT(pteval_t, 1) << 1)
12017f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define L_PTE_FILE		(_AT(pteval_t, 1) << 2)	/* only when !PRESENT */
12117f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define L_PTE_DIRTY		(_AT(pteval_t, 1) << 6)
12217f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define L_PTE_RDONLY		(_AT(pteval_t, 1) << 7)
12317f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define L_PTE_USER		(_AT(pteval_t, 1) << 8)
12417f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define L_PTE_XN		(_AT(pteval_t, 1) << 9)
12517f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define L_PTE_SHARED		(_AT(pteval_t, 1) << 10)	/* shared(v6), coherent(xsc3) */
12617f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas
12717f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas/*
12817f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * These are the memory types, defined to be compatible with
12917f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas * pre-ARMv6 CPUs cacheable and bufferable bits:   XXCB
13017f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas */
13117f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define L_PTE_MT_UNCACHED	(_AT(pteval_t, 0x00) << 2)	/* 0000 */
13217f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define L_PTE_MT_BUFFERABLE	(_AT(pteval_t, 0x01) << 2)	/* 0001 */
13317f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define L_PTE_MT_WRITETHROUGH	(_AT(pteval_t, 0x02) << 2)	/* 0010 */
13417f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define L_PTE_MT_WRITEBACK	(_AT(pteval_t, 0x03) << 2)	/* 0011 */
13517f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define L_PTE_MT_MINICACHE	(_AT(pteval_t, 0x06) << 2)	/* 0110 (sa1100, xscale) */
13617f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define L_PTE_MT_WRITEALLOC	(_AT(pteval_t, 0x07) << 2)	/* 0111 */
13717f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define L_PTE_MT_DEV_SHARED	(_AT(pteval_t, 0x04) << 2)	/* 0100 */
13817f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define L_PTE_MT_DEV_NONSHARED	(_AT(pteval_t, 0x0c) << 2)	/* 1100 */
13917f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define L_PTE_MT_DEV_WC		(_AT(pteval_t, 0x09) << 2)	/* 1001 */
14017f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define L_PTE_MT_DEV_CACHED	(_AT(pteval_t, 0x0b) << 2)	/* 1011 */
14117f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#define L_PTE_MT_MASK		(_AT(pteval_t, 0x0f) << 2)
14217f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas
143e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas#ifndef __ASSEMBLY__
144e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas
145e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas/*
146e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas * The "pud_xxx()" functions here are trivial when the pmd is folded into
147e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas * the pud: the pud entry is never bad, always exists, and can't be set or
148e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas * cleared.
149e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas */
150e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas#define pud_none(pud)		(0)
151e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas#define pud_bad(pud)		(0)
152e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas#define pud_present(pud)	(1)
153e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas#define pud_clear(pudp)		do { } while (0)
154e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas#define set_pud(pud,pudp)	do { } while (0)
155e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas
156e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinasstatic inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
157e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas{
158e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas	return (pmd_t *)pud;
159e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas}
160e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas
161e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas#define pmd_bad(pmd)		(pmd_val(pmd) & 2)
162e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas
163e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas#define copy_pmd(pmdpd,pmdps)		\
164e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas	do {				\
165e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas		pmdpd[0] = pmdps[0];	\
166e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas		pmdpd[1] = pmdps[1];	\
167e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas		flush_pmd_entry(pmdpd);	\
168e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas	} while (0)
169e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas
170e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas#define pmd_clear(pmdp)			\
171e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas	do {				\
172e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas		pmdp[0] = __pmd(0);	\
173e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas		pmdp[1] = __pmd(0);	\
174e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas		clean_pmd_entry(pmdp);	\
175e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas	} while (0)
176e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas
177e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas/* we don't need complex calculations here as the pmd is folded into the pgd */
178e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas#define pmd_addr_end(addr,end) (end)
179e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas
180e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
181e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas
182e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas#endif /* __ASSEMBLY__ */
183e0c0313bd720977a7ed01dc48f0762a3ddec607fCatalin Marinas
18417f57211969bddca2e922299a2530b1c65ccabfaCatalin Marinas#endif /* _ASM_PGTABLE_2LEVEL_H */
185