mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-24 07:31:41 +00:00
Merge branch 'for-rmk' of git://git.kernel.org/pub/scm/linux/kernel/git/cmarinas/linux into devel-stable
Conflicts: arch/arm/mm/ioremap.c
This commit is contained in:
commit
6ae25a5b9d
32 changed files with 1199 additions and 322 deletions
|
@ -186,6 +186,17 @@
|
|||
#define ALT_UP_B(label) b label
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Instruction barrier
|
||||
*/
|
||||
.macro instr_sync
|
||||
#if __LINUX_ARM_ARCH__ >= 7
|
||||
isb
|
||||
#elif __LINUX_ARM_ARCH__ == 6
|
||||
mcr p15, 0, r0, c7, c5, 4
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
* SMP data memory barrier
|
||||
*/
|
||||
|
|
|
@ -151,7 +151,11 @@ extern void __cpu_copy_user_highpage(struct page *to, struct page *from,
|
|||
#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
|
||||
extern void copy_page(void *to, const void *from);
|
||||
|
||||
#ifdef CONFIG_ARM_LPAE
|
||||
#include <asm/pgtable-3level-types.h>
|
||||
#else
|
||||
#include <asm/pgtable-2level-types.h>
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_MMU */
|
||||
|
||||
|
|
|
@ -25,12 +25,34 @@
|
|||
#define _PAGE_USER_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_USER))
|
||||
#define _PAGE_KERNEL_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_KERNEL))
|
||||
|
||||
#ifdef CONFIG_ARM_LPAE
|
||||
|
||||
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
|
||||
{
|
||||
return (pmd_t *)get_zeroed_page(GFP_KERNEL | __GFP_REPEAT);
|
||||
}
|
||||
|
||||
static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
|
||||
{
|
||||
BUG_ON((unsigned long)pmd & (PAGE_SIZE-1));
|
||||
free_page((unsigned long)pmd);
|
||||
}
|
||||
|
||||
static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
|
||||
{
|
||||
set_pud(pud, __pud(__pa(pmd) | PMD_TYPE_TABLE));
|
||||
}
|
||||
|
||||
#else /* !CONFIG_ARM_LPAE */
|
||||
|
||||
/*
|
||||
* Since we have only two-level page tables, these are trivial
|
||||
*/
|
||||
#define pmd_alloc_one(mm,addr) ({ BUG(); ((pmd_t *)2); })
|
||||
#define pmd_free(mm, pmd) do { } while (0)
|
||||
#define pgd_populate(mm,pmd,pte) BUG()
|
||||
#define pud_populate(mm,pmd,pte) BUG()
|
||||
|
||||
#endif /* CONFIG_ARM_LPAE */
|
||||
|
||||
extern pgd_t *pgd_alloc(struct mm_struct *mm);
|
||||
extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
|
||||
|
@ -109,7 +131,9 @@ static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t pte,
|
|||
{
|
||||
pmdval_t pmdval = (pte + PTE_HWTABLE_OFF) | prot;
|
||||
pmdp[0] = __pmd(pmdval);
|
||||
#ifndef CONFIG_ARM_LPAE
|
||||
pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t));
|
||||
#endif
|
||||
flush_pmd_entry(pmdp);
|
||||
}
|
||||
|
||||
|
|
|
@ -140,4 +140,45 @@
|
|||
#define L_PTE_MT_DEV_CACHED (_AT(pteval_t, 0x0b) << 2) /* 1011 */
|
||||
#define L_PTE_MT_MASK (_AT(pteval_t, 0x0f) << 2)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/*
|
||||
* The "pud_xxx()" functions here are trivial when the pmd is folded into
|
||||
* the pud: the pud entry is never bad, always exists, and can't be set or
|
||||
* cleared.
|
||||
*/
|
||||
#define pud_none(pud) (0)
|
||||
#define pud_bad(pud) (0)
|
||||
#define pud_present(pud) (1)
|
||||
#define pud_clear(pudp) do { } while (0)
|
||||
#define set_pud(pud,pudp) do { } while (0)
|
||||
|
||||
static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
|
||||
{
|
||||
return (pmd_t *)pud;
|
||||
}
|
||||
|
||||
#define pmd_bad(pmd) (pmd_val(pmd) & 2)
|
||||
|
||||
#define copy_pmd(pmdpd,pmdps) \
|
||||
do { \
|
||||
pmdpd[0] = pmdps[0]; \
|
||||
pmdpd[1] = pmdps[1]; \
|
||||
flush_pmd_entry(pmdpd); \
|
||||
} while (0)
|
||||
|
||||
#define pmd_clear(pmdp) \
|
||||
do { \
|
||||
pmdp[0] = __pmd(0); \
|
||||
pmdp[1] = __pmd(0); \
|
||||
clean_pmd_entry(pmdp); \
|
||||
} while (0)
|
||||
|
||||
/* we don't need complex calculations here as the pmd is folded into the pgd */
|
||||
#define pmd_addr_end(addr,end) (end)
|
||||
|
||||
#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_PGTABLE_2LEVEL_H */
|
||||
|
|
77
arch/arm/include/asm/pgtable-3level-hwdef.h
Normal file
77
arch/arm/include/asm/pgtable-3level-hwdef.h
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* arch/arm/include/asm/pgtable-3level-hwdef.h
|
||||
*
|
||||
* Copyright (C) 2011 ARM Ltd.
|
||||
* Author: Catalin Marinas <catalin.marinas@arm.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef _ASM_PGTABLE_3LEVEL_HWDEF_H
|
||||
#define _ASM_PGTABLE_3LEVEL_HWDEF_H
|
||||
|
||||
/*
|
||||
* Hardware page table definitions.
|
||||
*
|
||||
* + Level 1/2 descriptor
|
||||
* - common
|
||||
*/
|
||||
#define PMD_TYPE_MASK (_AT(pmdval_t, 3) << 0)
|
||||
#define PMD_TYPE_FAULT (_AT(pmdval_t, 0) << 0)
|
||||
#define PMD_TYPE_TABLE (_AT(pmdval_t, 3) << 0)
|
||||
#define PMD_TYPE_SECT (_AT(pmdval_t, 1) << 0)
|
||||
#define PMD_BIT4 (_AT(pmdval_t, 0))
|
||||
#define PMD_DOMAIN(x) (_AT(pmdval_t, 0))
|
||||
|
||||
/*
|
||||
* - section
|
||||
*/
|
||||
#define PMD_SECT_BUFFERABLE (_AT(pmdval_t, 1) << 2)
|
||||
#define PMD_SECT_CACHEABLE (_AT(pmdval_t, 1) << 3)
|
||||
#define PMD_SECT_S (_AT(pmdval_t, 3) << 8)
|
||||
#define PMD_SECT_AF (_AT(pmdval_t, 1) << 10)
|
||||
#define PMD_SECT_nG (_AT(pmdval_t, 1) << 11)
|
||||
#define PMD_SECT_XN (_AT(pmdval_t, 1) << 54)
|
||||
#define PMD_SECT_AP_WRITE (_AT(pmdval_t, 0))
|
||||
#define PMD_SECT_AP_READ (_AT(pmdval_t, 0))
|
||||
#define PMD_SECT_TEX(x) (_AT(pmdval_t, 0))
|
||||
|
||||
/*
|
||||
* AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers).
|
||||
*/
|
||||
#define PMD_SECT_UNCACHED (_AT(pmdval_t, 0) << 2) /* strongly ordered */
|
||||
#define PMD_SECT_BUFFERED (_AT(pmdval_t, 1) << 2) /* normal non-cacheable */
|
||||
#define PMD_SECT_WT (_AT(pmdval_t, 2) << 2) /* normal inner write-through */
|
||||
#define PMD_SECT_WB (_AT(pmdval_t, 3) << 2) /* normal inner write-back */
|
||||
#define PMD_SECT_WBWA (_AT(pmdval_t, 7) << 2) /* normal inner write-alloc */
|
||||
|
||||
/*
|
||||
* + Level 3 descriptor (PTE)
|
||||
*/
|
||||
#define PTE_TYPE_MASK (_AT(pteval_t, 3) << 0)
|
||||
#define PTE_TYPE_FAULT (_AT(pteval_t, 0) << 0)
|
||||
#define PTE_TYPE_PAGE (_AT(pteval_t, 3) << 0)
|
||||
#define PTE_BUFFERABLE (_AT(pteval_t, 1) << 2) /* AttrIndx[0] */
|
||||
#define PTE_CACHEABLE (_AT(pteval_t, 1) << 3) /* AttrIndx[1] */
|
||||
#define PTE_EXT_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */
|
||||
#define PTE_EXT_AF (_AT(pteval_t, 1) << 10) /* Access Flag */
|
||||
#define PTE_EXT_NG (_AT(pteval_t, 1) << 11) /* nG */
|
||||
#define PTE_EXT_XN (_AT(pteval_t, 1) << 54) /* XN */
|
||||
|
||||
/*
|
||||
* 40-bit physical address supported.
|
||||
*/
|
||||
#define PHYS_MASK_SHIFT (40)
|
||||
#define PHYS_MASK ((1ULL << PHYS_MASK_SHIFT) - 1)
|
||||
|
||||
#endif
|
70
arch/arm/include/asm/pgtable-3level-types.h
Normal file
70
arch/arm/include/asm/pgtable-3level-types.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* arch/arm/include/asm/pgtable-3level-types.h
|
||||
*
|
||||
* Copyright (C) 2011 ARM Ltd.
|
||||
* Author: Catalin Marinas <catalin.marinas@arm.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef _ASM_PGTABLE_3LEVEL_TYPES_H
|
||||
#define _ASM_PGTABLE_3LEVEL_TYPES_H
|
||||
|
||||
#include <asm/types.h>
|
||||
|
||||
typedef u64 pteval_t;
|
||||
typedef u64 pmdval_t;
|
||||
typedef u64 pgdval_t;
|
||||
|
||||
#undef STRICT_MM_TYPECHECKS
|
||||
|
||||
#ifdef STRICT_MM_TYPECHECKS
|
||||
|
||||
/*
|
||||
* These are used to make use of C type-checking..
|
||||
*/
|
||||
typedef struct { pteval_t pte; } pte_t;
|
||||
typedef struct { pmdval_t pmd; } pmd_t;
|
||||
typedef struct { pgdval_t pgd; } pgd_t;
|
||||
typedef struct { pteval_t pgprot; } pgprot_t;
|
||||
|
||||
#define pte_val(x) ((x).pte)
|
||||
#define pmd_val(x) ((x).pmd)
|
||||
#define pgd_val(x) ((x).pgd)
|
||||
#define pgprot_val(x) ((x).pgprot)
|
||||
|
||||
#define __pte(x) ((pte_t) { (x) } )
|
||||
#define __pmd(x) ((pmd_t) { (x) } )
|
||||
#define __pgd(x) ((pgd_t) { (x) } )
|
||||
#define __pgprot(x) ((pgprot_t) { (x) } )
|
||||
|
||||
#else /* !STRICT_MM_TYPECHECKS */
|
||||
|
||||
typedef pteval_t pte_t;
|
||||
typedef pmdval_t pmd_t;
|
||||
typedef pgdval_t pgd_t;
|
||||
typedef pteval_t pgprot_t;
|
||||
|
||||
#define pte_val(x) (x)
|
||||
#define pmd_val(x) (x)
|
||||
#define pgd_val(x) (x)
|
||||
#define pgprot_val(x) (x)
|
||||
|
||||
#define __pte(x) (x)
|
||||
#define __pmd(x) (x)
|
||||
#define __pgd(x) (x)
|
||||
#define __pgprot(x) (x)
|
||||
|
||||
#endif /* STRICT_MM_TYPECHECKS */
|
||||
|
||||
#endif /* _ASM_PGTABLE_3LEVEL_TYPES_H */
|
155
arch/arm/include/asm/pgtable-3level.h
Normal file
155
arch/arm/include/asm/pgtable-3level.h
Normal file
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* arch/arm/include/asm/pgtable-3level.h
|
||||
*
|
||||
* Copyright (C) 2011 ARM Ltd.
|
||||
* Author: Catalin Marinas <catalin.marinas@arm.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef _ASM_PGTABLE_3LEVEL_H
|
||||
#define _ASM_PGTABLE_3LEVEL_H
|
||||
|
||||
/*
|
||||
* With LPAE, there are 3 levels of page tables. Each level has 512 entries of
|
||||
* 8 bytes each, occupying a 4K page. The first level table covers a range of
|
||||
* 512GB, each entry representing 1GB. Since we are limited to 4GB input
|
||||
* address range, only 4 entries in the PGD are used.
|
||||
*
|
||||
* There are enough spare bits in a page table entry for the kernel specific
|
||||
* state.
|
||||
*/
|
||||
#define PTRS_PER_PTE 512
|
||||
#define PTRS_PER_PMD 512
|
||||
#define PTRS_PER_PGD 4
|
||||
|
||||
#define PTE_HWTABLE_PTRS (PTRS_PER_PTE)
|
||||
#define PTE_HWTABLE_OFF (0)
|
||||
#define PTE_HWTABLE_SIZE (PTRS_PER_PTE * sizeof(u64))
|
||||
|
||||
/*
|
||||
* PGDIR_SHIFT determines the size a top-level page table entry can map.
|
||||
*/
|
||||
#define PGDIR_SHIFT 30
|
||||
|
||||
/*
|
||||
* PMD_SHIFT determines the size a middle-level page table entry can map.
|
||||
*/
|
||||
#define PMD_SHIFT 21
|
||||
|
||||
#define PMD_SIZE (1UL << PMD_SHIFT)
|
||||
#define PMD_MASK (~(PMD_SIZE-1))
|
||||
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
|
||||
#define PGDIR_MASK (~(PGDIR_SIZE-1))
|
||||
|
||||
/*
|
||||
* section address mask and size definitions.
|
||||
*/
|
||||
#define SECTION_SHIFT 21
|
||||
#define SECTION_SIZE (1UL << SECTION_SHIFT)
|
||||
#define SECTION_MASK (~(SECTION_SIZE-1))
|
||||
|
||||
#define USER_PTRS_PER_PGD (PAGE_OFFSET / PGDIR_SIZE)
|
||||
|
||||
/*
|
||||
* "Linux" PTE definitions for LPAE.
|
||||
*
|
||||
* These bits overlap with the hardware bits but the naming is preserved for
|
||||
* consistency with the classic page table format.
|
||||
*/
|
||||
#define L_PTE_PRESENT (_AT(pteval_t, 3) << 0) /* Valid */
|
||||
#define L_PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !PRESENT */
|
||||
#define L_PTE_BUFFERABLE (_AT(pteval_t, 1) << 2) /* AttrIndx[0] */
|
||||
#define L_PTE_CACHEABLE (_AT(pteval_t, 1) << 3) /* AttrIndx[1] */
|
||||
#define L_PTE_USER (_AT(pteval_t, 1) << 6) /* AP[1] */
|
||||
#define L_PTE_RDONLY (_AT(pteval_t, 1) << 7) /* AP[2] */
|
||||
#define L_PTE_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */
|
||||
#define L_PTE_YOUNG (_AT(pteval_t, 1) << 10) /* AF */
|
||||
#define L_PTE_XN (_AT(pteval_t, 1) << 54) /* XN */
|
||||
#define L_PTE_DIRTY (_AT(pteval_t, 1) << 55) /* unused */
|
||||
#define L_PTE_SPECIAL (_AT(pteval_t, 1) << 56) /* unused */
|
||||
|
||||
/*
|
||||
* To be used in assembly code with the upper page attributes.
|
||||
*/
|
||||
#define L_PTE_XN_HIGH (1 << (54 - 32))
|
||||
#define L_PTE_DIRTY_HIGH (1 << (55 - 32))
|
||||
|
||||
/*
|
||||
* AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers).
|
||||
*/
|
||||
#define L_PTE_MT_UNCACHED (_AT(pteval_t, 0) << 2) /* strongly ordered */
|
||||
#define L_PTE_MT_BUFFERABLE (_AT(pteval_t, 1) << 2) /* normal non-cacheable */
|
||||
#define L_PTE_MT_WRITETHROUGH (_AT(pteval_t, 2) << 2) /* normal inner write-through */
|
||||
#define L_PTE_MT_WRITEBACK (_AT(pteval_t, 3) << 2) /* normal inner write-back */
|
||||
#define L_PTE_MT_WRITEALLOC (_AT(pteval_t, 7) << 2) /* normal inner write-alloc */
|
||||
#define L_PTE_MT_DEV_SHARED (_AT(pteval_t, 4) << 2) /* device */
|
||||
#define L_PTE_MT_DEV_NONSHARED (_AT(pteval_t, 4) << 2) /* device */
|
||||
#define L_PTE_MT_DEV_WC (_AT(pteval_t, 1) << 2) /* normal non-cacheable */
|
||||
#define L_PTE_MT_DEV_CACHED (_AT(pteval_t, 3) << 2) /* normal inner write-back */
|
||||
#define L_PTE_MT_MASK (_AT(pteval_t, 7) << 2)
|
||||
|
||||
/*
|
||||
* Software PGD flags.
|
||||
*/
|
||||
#define L_PGD_SWAPPER (_AT(pgdval_t, 1) << 55) /* swapper_pg_dir entry */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#define pud_none(pud) (!pud_val(pud))
|
||||
#define pud_bad(pud) (!(pud_val(pud) & 2))
|
||||
#define pud_present(pud) (pud_val(pud))
|
||||
|
||||
#define pud_clear(pudp) \
|
||||
do { \
|
||||
*pudp = __pud(0); \
|
||||
clean_pmd_entry(pudp); \
|
||||
} while (0)
|
||||
|
||||
#define set_pud(pudp, pud) \
|
||||
do { \
|
||||
*pudp = pud; \
|
||||
flush_pmd_entry(pudp); \
|
||||
} while (0)
|
||||
|
||||
static inline pmd_t *pud_page_vaddr(pud_t pud)
|
||||
{
|
||||
return __va(pud_val(pud) & PHYS_MASK & (s32)PAGE_MASK);
|
||||
}
|
||||
|
||||
/* Find an entry in the second-level page table.. */
|
||||
#define pmd_index(addr) (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
|
||||
static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
|
||||
{
|
||||
return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(addr);
|
||||
}
|
||||
|
||||
#define pmd_bad(pmd) (!(pmd_val(pmd) & 2))
|
||||
|
||||
#define copy_pmd(pmdpd,pmdps) \
|
||||
do { \
|
||||
*pmdpd = *pmdps; \
|
||||
flush_pmd_entry(pmdpd); \
|
||||
} while (0)
|
||||
|
||||
#define pmd_clear(pmdp) \
|
||||
do { \
|
||||
*pmdp = __pmd(0); \
|
||||
clean_pmd_entry(pmdp); \
|
||||
} while (0)
|
||||
|
||||
#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,__pte(pte_val(pte)|(ext)))
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_PGTABLE_3LEVEL_H */
|
|
@ -10,6 +10,10 @@
|
|||
#ifndef _ASMARM_PGTABLE_HWDEF_H
|
||||
#define _ASMARM_PGTABLE_HWDEF_H
|
||||
|
||||
#ifdef CONFIG_ARM_LPAE
|
||||
#include <asm/pgtable-3level-hwdef.h>
|
||||
#else
|
||||
#include <asm/pgtable-2level-hwdef.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -11,19 +11,24 @@
|
|||
#define _ASMARM_PGTABLE_H
|
||||
|
||||
#include <linux/const.h>
|
||||
#include <asm-generic/4level-fixup.h>
|
||||
#include <asm/proc-fns.h>
|
||||
|
||||
#ifndef CONFIG_MMU
|
||||
|
||||
#include <asm-generic/4level-fixup.h>
|
||||
#include "pgtable-nommu.h"
|
||||
|
||||
#else
|
||||
|
||||
#include <asm-generic/pgtable-nopud.h>
|
||||
#include <asm/memory.h>
|
||||
#include <asm/pgtable-hwdef.h>
|
||||
|
||||
#ifdef CONFIG_ARM_LPAE
|
||||
#include <asm/pgtable-3level.h>
|
||||
#else
|
||||
#include <asm/pgtable-2level.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Just any arbitrary offset to the start of the vmalloc VM area: the
|
||||
|
@ -164,39 +169,8 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
|
|||
/* to find an entry in a kernel page-table-directory */
|
||||
#define pgd_offset_k(addr) pgd_offset(&init_mm, addr)
|
||||
|
||||
/*
|
||||
* The "pgd_xxx()" functions here are trivial for a folded two-level
|
||||
* setup: the pgd is never bad, and a pmd always exists (as it's folded
|
||||
* into the pgd entry)
|
||||
*/
|
||||
#define pgd_none(pgd) (0)
|
||||
#define pgd_bad(pgd) (0)
|
||||
#define pgd_present(pgd) (1)
|
||||
#define pgd_clear(pgdp) do { } while (0)
|
||||
#define set_pgd(pgd,pgdp) do { } while (0)
|
||||
#define set_pud(pud,pudp) do { } while (0)
|
||||
|
||||
|
||||
/* Find an entry in the second-level page table.. */
|
||||
#define pmd_offset(dir, addr) ((pmd_t *)(dir))
|
||||
|
||||
#define pmd_none(pmd) (!pmd_val(pmd))
|
||||
#define pmd_present(pmd) (pmd_val(pmd))
|
||||
#define pmd_bad(pmd) (pmd_val(pmd) & 2)
|
||||
|
||||
#define copy_pmd(pmdpd,pmdps) \
|
||||
do { \
|
||||
pmdpd[0] = pmdps[0]; \
|
||||
pmdpd[1] = pmdps[1]; \
|
||||
flush_pmd_entry(pmdpd); \
|
||||
} while (0)
|
||||
|
||||
#define pmd_clear(pmdp) \
|
||||
do { \
|
||||
pmdp[0] = __pmd(0); \
|
||||
pmdp[1] = __pmd(0); \
|
||||
clean_pmd_entry(pmdp); \
|
||||
} while (0)
|
||||
|
||||
static inline pte_t *pmd_page_vaddr(pmd_t pmd)
|
||||
{
|
||||
|
@ -205,10 +179,6 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
|
|||
|
||||
#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
|
||||
|
||||
/* we don't need complex calculations here as the pmd is folded into the pgd */
|
||||
#define pmd_addr_end(addr,end) (end)
|
||||
|
||||
|
||||
#ifndef CONFIG_HIGHPTE
|
||||
#define __pte_map(pmd) pmd_page_vaddr(*(pmd))
|
||||
#define __pte_unmap(pte) do { } while (0)
|
||||
|
@ -230,7 +200,6 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
|
|||
#define pte_page(pte) pfn_to_page(pte_pfn(pte))
|
||||
#define mk_pte(page,prot) pfn_pte(page_to_pfn(page), prot)
|
||||
|
||||
#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext)
|
||||
#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0)
|
||||
|
||||
#if __LINUX_ARM_ARCH__ < 6
|
||||
|
|
|
@ -65,7 +65,11 @@ extern struct processor {
|
|||
* Set a possibly extended PTE. Non-extended PTEs should
|
||||
* ignore 'ext'.
|
||||
*/
|
||||
#ifdef CONFIG_ARM_LPAE
|
||||
void (*set_pte_ext)(pte_t *ptep, pte_t pte);
|
||||
#else
|
||||
void (*set_pte_ext)(pte_t *ptep, pte_t pte, unsigned int ext);
|
||||
#endif
|
||||
|
||||
/* Suspend/resume */
|
||||
unsigned int suspend_size;
|
||||
|
@ -79,7 +83,11 @@ extern void cpu_proc_fin(void);
|
|||
extern int cpu_do_idle(void);
|
||||
extern void cpu_dcache_clean_area(void *, int);
|
||||
extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
|
||||
#ifdef CONFIG_ARM_LPAE
|
||||
extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte);
|
||||
#else
|
||||
extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
|
||||
#endif
|
||||
extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
|
||||
|
||||
/* These three are private to arch/arm/kernel/suspend.c */
|
||||
|
@ -107,6 +115,18 @@ extern void cpu_resume(void);
|
|||
|
||||
#define cpu_switch_mm(pgd,mm) cpu_do_switch_mm(virt_to_phys(pgd),mm)
|
||||
|
||||
#ifdef CONFIG_ARM_LPAE
|
||||
#define cpu_get_pgd() \
|
||||
({ \
|
||||
unsigned long pg, pg2; \
|
||||
__asm__("mrrc p15, 0, %0, %1, c2" \
|
||||
: "=r" (pg), "=r" (pg2) \
|
||||
: \
|
||||
: "cc"); \
|
||||
pg &= ~(PTRS_PER_PGD*sizeof(pgd_t)-1); \
|
||||
(pgd_t *)phys_to_virt(pg); \
|
||||
})
|
||||
#else
|
||||
#define cpu_get_pgd() \
|
||||
({ \
|
||||
unsigned long pg; \
|
||||
|
@ -115,6 +135,7 @@ extern void cpu_resume(void);
|
|||
pg &= ~0x3fff; \
|
||||
(pgd_t *)phys_to_virt(pg); \
|
||||
})
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -80,6 +80,14 @@ struct siginfo;
|
|||
void arm_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
|
||||
unsigned long err, unsigned long trap);
|
||||
|
||||
#ifdef CONFIG_ARM_LPAE
|
||||
#define FAULT_CODE_ALIGNMENT 33
|
||||
#define FAULT_CODE_DEBUG 34
|
||||
#else
|
||||
#define FAULT_CODE_ALIGNMENT 1
|
||||
#define FAULT_CODE_DEBUG 2
|
||||
#endif
|
||||
|
||||
void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
|
||||
struct pt_regs *),
|
||||
int sig, int code, const char *name);
|
||||
|
|
|
@ -202,8 +202,18 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
|
|||
tlb_remove_page(tlb, pte);
|
||||
}
|
||||
|
||||
static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
|
||||
unsigned long addr)
|
||||
{
|
||||
#ifdef CONFIG_ARM_LPAE
|
||||
tlb_add_flush(tlb, addr);
|
||||
tlb_remove_page(tlb, virt_to_page(pmdp));
|
||||
#endif
|
||||
}
|
||||
|
||||
#define pte_free_tlb(tlb, ptep, addr) __pte_free_tlb(tlb, ptep, addr)
|
||||
#define pmd_free_tlb(tlb, pmdp, addr) pmd_free((tlb)->mm, pmdp)
|
||||
#define pmd_free_tlb(tlb, pmdp, addr) __pmd_free_tlb(tlb, pmdp, addr)
|
||||
#define pud_free_tlb(tlb, pudp, addr) pud_free((tlb)->mm, pudp)
|
||||
|
||||
#define tlb_migrate_finish(mm) do { } while (0)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue