Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
28cdac66
Commit
28cdac66
authored
Jan 06, 2011
by
Russell King
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'pgt' (early part) into devel
parents
4073723a
36bb94ba
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
315 additions
and
332 deletions
+315
-332
arch/arm/include/asm/page.h
arch/arm/include/asm/page.h
+4
-2
arch/arm/include/asm/pgalloc.h
arch/arm/include/asm/pgalloc.h
+22
-28
arch/arm/include/asm/pgtable.h
arch/arm/include/asm/pgtable.h
+155
-160
arch/arm/kernel/smp.c
arch/arm/kernel/smp.c
+0
-36
arch/arm/kernel/traps.c
arch/arm/kernel/traps.c
+6
-6
arch/arm/mm/Makefile
arch/arm/mm/Makefile
+2
-2
arch/arm/mm/fault-armv.c
arch/arm/mm/fault-armv.c
+1
-1
arch/arm/mm/fault.c
arch/arm/mm/fault.c
+1
-1
arch/arm/mm/idmap.c
arch/arm/mm/idmap.c
+67
-0
arch/arm/mm/mm.h
arch/arm/mm/mm.h
+1
-1
arch/arm/mm/mmu.c
arch/arm/mm/mmu.c
+13
-49
arch/arm/mm/pgd.c
arch/arm/mm/pgd.c
+18
-19
arch/arm/mm/proc-macros.S
arch/arm/mm/proc-macros.S
+15
-15
arch/arm/mm/proc-v7.S
arch/arm/mm/proc-v7.S
+8
-10
arch/arm/mm/proc-xscale.S
arch/arm/mm/proc-xscale.S
+2
-2
No files found.
arch/arm/include/asm/page.h
View file @
28cdac66
...
@@ -151,13 +151,15 @@ extern void __cpu_copy_user_highpage(struct page *to, struct page *from,
...
@@ -151,13 +151,15 @@ extern void __cpu_copy_user_highpage(struct page *to, struct page *from,
#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
extern
void
copy_page
(
void
*
to
,
const
void
*
from
);
extern
void
copy_page
(
void
*
to
,
const
void
*
from
);
typedef
unsigned
long
pteval_t
;
#undef STRICT_MM_TYPECHECKS
#undef STRICT_MM_TYPECHECKS
#ifdef STRICT_MM_TYPECHECKS
#ifdef STRICT_MM_TYPECHECKS
/*
/*
* These are used to make use of C type-checking..
* These are used to make use of C type-checking..
*/
*/
typedef
struct
{
unsigned
long
pte
;
}
pte_t
;
typedef
struct
{
pteval_t
pte
;
}
pte_t
;
typedef
struct
{
unsigned
long
pmd
;
}
pmd_t
;
typedef
struct
{
unsigned
long
pmd
;
}
pmd_t
;
typedef
struct
{
unsigned
long
pgd
[
2
];
}
pgd_t
;
typedef
struct
{
unsigned
long
pgd
[
2
];
}
pgd_t
;
typedef
struct
{
unsigned
long
pgprot
;
}
pgprot_t
;
typedef
struct
{
unsigned
long
pgprot
;
}
pgprot_t
;
...
@@ -175,7 +177,7 @@ typedef struct { unsigned long pgprot; } pgprot_t;
...
@@ -175,7 +177,7 @@ typedef struct { unsigned long pgprot; } pgprot_t;
/*
/*
* .. while these make it easier on the compiler
* .. while these make it easier on the compiler
*/
*/
typedef
unsigned
long
pte_t
;
typedef
pteval_t
pte_t
;
typedef
unsigned
long
pmd_t
;
typedef
unsigned
long
pmd_t
;
typedef
unsigned
long
pgd_t
[
2
];
typedef
unsigned
long
pgd_t
[
2
];
typedef
unsigned
long
pgprot_t
;
typedef
unsigned
long
pgprot_t
;
...
...
arch/arm/include/asm/pgalloc.h
View file @
28cdac66
...
@@ -30,14 +30,16 @@
...
@@ -30,14 +30,16 @@
#define pmd_free(mm, pmd) do { } while (0)
#define pmd_free(mm, pmd) do { } while (0)
#define pgd_populate(mm,pmd,pte) BUG()
#define pgd_populate(mm,pmd,pte) BUG()
extern
pgd_t
*
get_pgd_slow
(
struct
mm_struct
*
mm
);
extern
pgd_t
*
pgd_alloc
(
struct
mm_struct
*
mm
);
extern
void
free_pgd_slow
(
struct
mm_struct
*
mm
,
pgd_t
*
pgd
);
extern
void
pgd_free
(
struct
mm_struct
*
mm
,
pgd_t
*
pgd
);
#define pgd_alloc(mm) get_pgd_slow(mm)
#define pgd_free(mm, pgd) free_pgd_slow(mm, pgd)
#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO)
#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO)
static
inline
void
clean_pte_table
(
pte_t
*
pte
)
{
clean_dcache_area
(
pte
+
PTE_HWTABLE_PTRS
,
PTE_HWTABLE_SIZE
);
}
/*
/*
* Allocate one PTE table.
* Allocate one PTE table.
*
*
...
@@ -45,14 +47,14 @@ extern void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd);
...
@@ -45,14 +47,14 @@ extern void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd);
* into one table thus:
* into one table thus:
*
*
* +------------+
* +------------+
* | h/w pt 0 |
* +------------+
* | h/w pt 1 |
* +------------+
* | Linux pt 0 |
* | Linux pt 0 |
* +------------+
* +------------+
* | Linux pt 1 |
* | Linux pt 1 |
* +------------+
* +------------+
* | h/w pt 0 |
* +------------+
* | h/w pt 1 |
* +------------+
*/
*/
static
inline
pte_t
*
static
inline
pte_t
*
pte_alloc_one_kernel
(
struct
mm_struct
*
mm
,
unsigned
long
addr
)
pte_alloc_one_kernel
(
struct
mm_struct
*
mm
,
unsigned
long
addr
)
...
@@ -60,10 +62,8 @@ pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
...
@@ -60,10 +62,8 @@ pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
pte_t
*
pte
;
pte_t
*
pte
;
pte
=
(
pte_t
*
)
__get_free_page
(
PGALLOC_GFP
);
pte
=
(
pte_t
*
)
__get_free_page
(
PGALLOC_GFP
);
if
(
pte
)
{
if
(
pte
)
clean_dcache_area
(
pte
,
sizeof
(
pte_t
)
*
PTRS_PER_PTE
);
clean_pte_table
(
pte
);
pte
+=
PTRS_PER_PTE
;
}
return
pte
;
return
pte
;
}
}
...
@@ -79,10 +79,8 @@ pte_alloc_one(struct mm_struct *mm, unsigned long addr)
...
@@ -79,10 +79,8 @@ pte_alloc_one(struct mm_struct *mm, unsigned long addr)
pte
=
alloc_pages
(
PGALLOC_GFP
,
0
);
pte
=
alloc_pages
(
PGALLOC_GFP
,
0
);
#endif
#endif
if
(
pte
)
{
if
(
pte
)
{
if
(
!
PageHighMem
(
pte
))
{
if
(
!
PageHighMem
(
pte
))
void
*
page
=
page_address
(
pte
);
clean_pte_table
(
page_address
(
pte
));
clean_dcache_area
(
page
,
sizeof
(
pte_t
)
*
PTRS_PER_PTE
);
}
pgtable_page_ctor
(
pte
);
pgtable_page_ctor
(
pte
);
}
}
...
@@ -94,10 +92,8 @@ pte_alloc_one(struct mm_struct *mm, unsigned long addr)
...
@@ -94,10 +92,8 @@ pte_alloc_one(struct mm_struct *mm, unsigned long addr)
*/
*/
static
inline
void
pte_free_kernel
(
struct
mm_struct
*
mm
,
pte_t
*
pte
)
static
inline
void
pte_free_kernel
(
struct
mm_struct
*
mm
,
pte_t
*
pte
)
{
{
if
(
pte
)
{
if
(
pte
)
pte
-=
PTRS_PER_PTE
;
free_page
((
unsigned
long
)
pte
);
free_page
((
unsigned
long
)
pte
);
}
}
}
static
inline
void
pte_free
(
struct
mm_struct
*
mm
,
pgtable_t
pte
)
static
inline
void
pte_free
(
struct
mm_struct
*
mm
,
pgtable_t
pte
)
...
@@ -106,8 +102,10 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
...
@@ -106,8 +102,10 @@ static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
__free_page
(
pte
);
__free_page
(
pte
);
}
}
static
inline
void
__pmd_populate
(
pmd_t
*
pmdp
,
unsigned
long
pmdval
)
static
inline
void
__pmd_populate
(
pmd_t
*
pmdp
,
phys_addr_t
pte
,
unsigned
long
prot
)
{
{
unsigned
long
pmdval
=
(
pte
+
PTE_HWTABLE_OFF
)
|
prot
;
pmdp
[
0
]
=
__pmd
(
pmdval
);
pmdp
[
0
]
=
__pmd
(
pmdval
);
pmdp
[
1
]
=
__pmd
(
pmdval
+
256
*
sizeof
(
pte_t
));
pmdp
[
1
]
=
__pmd
(
pmdval
+
256
*
sizeof
(
pte_t
));
flush_pmd_entry
(
pmdp
);
flush_pmd_entry
(
pmdp
);
...
@@ -122,20 +120,16 @@ static inline void __pmd_populate(pmd_t *pmdp, unsigned long pmdval)
...
@@ -122,20 +120,16 @@ static inline void __pmd_populate(pmd_t *pmdp, unsigned long pmdval)
static
inline
void
static
inline
void
pmd_populate_kernel
(
struct
mm_struct
*
mm
,
pmd_t
*
pmdp
,
pte_t
*
ptep
)
pmd_populate_kernel
(
struct
mm_struct
*
mm
,
pmd_t
*
pmdp
,
pte_t
*
ptep
)
{
{
unsigned
long
pte_ptr
=
(
unsigned
long
)
ptep
;
/*
/*
* The pmd must be loaded with the physical
* The pmd must be loaded with the physical address of the PTE table
* address of the PTE table
*/
*/
pte_ptr
-=
PTRS_PER_PTE
*
sizeof
(
void
*
);
__pmd_populate
(
pmdp
,
__pa
(
ptep
),
_PAGE_KERNEL_TABLE
);
__pmd_populate
(
pmdp
,
__pa
(
pte_ptr
)
|
_PAGE_KERNEL_TABLE
);
}
}
static
inline
void
static
inline
void
pmd_populate
(
struct
mm_struct
*
mm
,
pmd_t
*
pmdp
,
pgtable_t
ptep
)
pmd_populate
(
struct
mm_struct
*
mm
,
pmd_t
*
pmdp
,
pgtable_t
ptep
)
{
{
__pmd_populate
(
pmdp
,
page_to_p
fn
(
ptep
)
<<
PAGE_SHIFT
|
_PAGE_USER_TABLE
);
__pmd_populate
(
pmdp
,
page_to_p
hys
(
ptep
),
_PAGE_USER_TABLE
);
}
}
#define pmd_pgtable(pmd) pmd_page(pmd)
#define pmd_pgtable(pmd) pmd_page(pmd)
...
...
arch/arm/include/asm/pgtable.h
View file @
28cdac66
...
@@ -10,6 +10,7 @@
...
@@ -10,6 +10,7 @@
#ifndef _ASMARM_PGTABLE_H
#ifndef _ASMARM_PGTABLE_H
#define _ASMARM_PGTABLE_H
#define _ASMARM_PGTABLE_H
#include <linux/const.h>
#include <asm-generic/4level-fixup.h>
#include <asm-generic/4level-fixup.h>
#include <asm/proc-fns.h>
#include <asm/proc-fns.h>
...
@@ -54,7 +55,7 @@
...
@@ -54,7 +55,7 @@
* Therefore, we tweak the implementation slightly - we tell Linux that we
* Therefore, we tweak the implementation slightly - we tell Linux that we
* have 2048 entries in the first level, each of which is 8 bytes (iow, two
* have 2048 entries in the first level, each of which is 8 bytes (iow, two
* hardware pointers to the second level.) The second level contains two
* hardware pointers to the second level.) The second level contains two
* hardware PTE tables arranged contiguously,
follow
ed by Linux versions
* hardware PTE tables arranged contiguously,
preced
ed by Linux versions
* which contain the state information Linux needs. We, therefore, end up
* which contain the state information Linux needs. We, therefore, end up
* with 512 entries in the "PTE" level.
* with 512 entries in the "PTE" level.
*
*
...
@@ -62,15 +63,15 @@
...
@@ -62,15 +63,15 @@
*
*
* pgd pte
* pgd pte
* | |
* | |
* +--------+ +0
* +--------+
* | |-----> +------------+ +0
* | | +------------+ +0
* +- - - - + | Linux pt 0 |
* | | +------------+ +1024
* +--------+ +0 | Linux pt 1 |
* | |-----> +------------+ +2048
* +- - - - + +4 | h/w pt 0 |
* +- - - - + +4 | h/w pt 0 |
* | |-----> +------------+ +
1024
* | |-----> +------------+ +
3072
* +--------+ +8 | h/w pt 1 |
* +--------+ +8 | h/w pt 1 |
* | | +------------+ +2048
* +- - - - + | Linux pt 0 |
* | | +------------+ +3072
* +--------+ | Linux pt 1 |
* | | +------------+ +4096
* | | +------------+ +4096
*
*
* See L_PTE_xxx below for definitions of bits in the "Linux pt", and
* See L_PTE_xxx below for definitions of bits in the "Linux pt", and
...
@@ -102,6 +103,10 @@
...
@@ -102,6 +103,10 @@
#define PTRS_PER_PMD 1
#define PTRS_PER_PMD 1
#define PTRS_PER_PGD 2048
#define PTRS_PER_PGD 2048
#define PTE_HWTABLE_PTRS (PTRS_PER_PTE)
#define PTE_HWTABLE_OFF (PTE_HWTABLE_PTRS * sizeof(pte_t))
#define PTE_HWTABLE_SIZE (PTRS_PER_PTE * sizeof(u32))
/*
/*
* PMD_SHIFT determines the size of the area a second-level page table can map
* PMD_SHIFT determines the size of the area a second-level page table can map
* PGDIR_SHIFT determines what a third-level page table entry can map
* PGDIR_SHIFT determines what a third-level page table entry can map
...
@@ -112,13 +117,13 @@
...
@@ -112,13 +117,13 @@
#define LIBRARY_TEXT_START 0x0c000000
#define LIBRARY_TEXT_START 0x0c000000
#ifndef __ASSEMBLY__
#ifndef __ASSEMBLY__
extern
void
__pte_error
(
const
char
*
file
,
int
line
,
unsigned
long
val
);
extern
void
__pte_error
(
const
char
*
file
,
int
line
,
pte_t
);
extern
void
__pmd_error
(
const
char
*
file
,
int
line
,
unsigned
long
val
);
extern
void
__pmd_error
(
const
char
*
file
,
int
line
,
pmd_t
);
extern
void
__pgd_error
(
const
char
*
file
,
int
line
,
unsigned
long
val
);
extern
void
__pgd_error
(
const
char
*
file
,
int
line
,
pgd_t
);
#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte
_val(pte)
)
#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte)
#define pmd_ERROR(pmd) __pmd_error(__FILE__, __LINE__, pmd
_val(pmd)
)
#define pmd_ERROR(pmd) __pmd_error(__FILE__, __LINE__, pmd)
#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd
_val(pgd)
)
#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd)
#endif
/* !__ASSEMBLY__ */
#endif
/* !__ASSEMBLY__ */
#define PMD_SIZE (1UL << PMD_SHIFT)
#define PMD_SIZE (1UL << PMD_SHIFT)
...
@@ -133,8 +138,7 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
...
@@ -133,8 +138,7 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
*/
*/
#define FIRST_USER_ADDRESS PAGE_SIZE
#define FIRST_USER_ADDRESS PAGE_SIZE
#define FIRST_USER_PGD_NR 1
#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE)
#define USER_PTRS_PER_PGD ((TASK_SIZE/PGDIR_SIZE) - FIRST_USER_PGD_NR)
/*
/*
* section address mask and size definitions.
* section address mask and size definitions.
...
@@ -161,30 +165,30 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
...
@@ -161,30 +165,30 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
* The PTE table pointer refers to the hardware entries; the "Linux"
* The PTE table pointer refers to the hardware entries; the "Linux"
* entries are stored 1024 bytes below.
* entries are stored 1024 bytes below.
*/
*/
#define L_PTE_PRESENT (
1
<< 0)
#define L_PTE_PRESENT (
_AT(pteval_t, 1)
<< 0)
#define L_PTE_YOUNG (
1
<< 1)
#define L_PTE_YOUNG (
_AT(pteval_t, 1)
<< 1)
#define L_PTE_FILE (
1
<< 2)
/* only when !PRESENT */
#define L_PTE_FILE (
_AT(pteval_t, 1)
<< 2)
/* only when !PRESENT */
#define L_PTE_DIRTY (
1
<< 6)
#define L_PTE_DIRTY (
_AT(pteval_t, 1)
<< 6)
#define L_PTE_
WRITE (1
<< 7)
#define L_PTE_
RDONLY (_AT(pteval_t, 1)
<< 7)
#define L_PTE_USER (
1
<< 8)
#define L_PTE_USER (
_AT(pteval_t, 1)
<< 8)
#define L_PTE_
EXEC (1
<< 9)
#define L_PTE_
XN (_AT(pteval_t, 1)
<< 9)
#define L_PTE_SHARED (
1
<< 10)
/* shared(v6), coherent(xsc3) */
#define L_PTE_SHARED (
_AT(pteval_t, 1)
<< 10)
/* shared(v6), coherent(xsc3) */
/*
/*
* These are the memory types, defined to be compatible with
* These are the memory types, defined to be compatible with
* pre-ARMv6 CPUs cacheable and bufferable bits: XXCB
* pre-ARMv6 CPUs cacheable and bufferable bits: XXCB
*/
*/
#define L_PTE_MT_UNCACHED (
0x00
<< 2)
/* 0000 */
#define L_PTE_MT_UNCACHED (
_AT(pteval_t, 0x00)
<< 2)
/* 0000 */
#define L_PTE_MT_BUFFERABLE (
0x01
<< 2)
/* 0001 */
#define L_PTE_MT_BUFFERABLE (
_AT(pteval_t, 0x01)
<< 2)
/* 0001 */
#define L_PTE_MT_WRITETHROUGH (
0x02
<< 2)
/* 0010 */
#define L_PTE_MT_WRITETHROUGH (
_AT(pteval_t, 0x02)
<< 2)
/* 0010 */
#define L_PTE_MT_WRITEBACK (
0x03
<< 2)
/* 0011 */
#define L_PTE_MT_WRITEBACK (
_AT(pteval_t, 0x03)
<< 2)
/* 0011 */
#define L_PTE_MT_MINICACHE (
0x06
<< 2)
/* 0110 (sa1100, xscale) */
#define L_PTE_MT_MINICACHE (
_AT(pteval_t, 0x06)
<< 2)
/* 0110 (sa1100, xscale) */
#define L_PTE_MT_WRITEALLOC (
0x07
<< 2)
/* 0111 */
#define L_PTE_MT_WRITEALLOC (
_AT(pteval_t, 0x07)
<< 2)
/* 0111 */
#define L_PTE_MT_DEV_SHARED (
0x04
<< 2)
/* 0100 */
#define L_PTE_MT_DEV_SHARED (
_AT(pteval_t, 0x04)
<< 2)
/* 0100 */
#define L_PTE_MT_DEV_NONSHARED (
0x0c
<< 2)
/* 1100 */
#define L_PTE_MT_DEV_NONSHARED (
_AT(pteval_t, 0x0c)
<< 2)
/* 1100 */
#define L_PTE_MT_DEV_WC (
0x09
<< 2)
/* 1001 */
#define L_PTE_MT_DEV_WC (
_AT(pteval_t, 0x09)
<< 2)
/* 1001 */
#define L_PTE_MT_DEV_CACHED (
0x0b
<< 2)
/* 1011 */
#define L_PTE_MT_DEV_CACHED (
_AT(pteval_t, 0x0b)
<< 2)
/* 1011 */
#define L_PTE_MT_MASK (
0x0f
<< 2)
#define L_PTE_MT_MASK (
_AT(pteval_t, 0x0f)
<< 2)
#ifndef __ASSEMBLY__
#ifndef __ASSEMBLY__
...
@@ -201,23 +205,44 @@ extern pgprot_t pgprot_kernel;
...
@@ -201,23 +205,44 @@ extern pgprot_t pgprot_kernel;
#define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b))
#define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b))
#define PAGE_NONE pgprot_user
#define PAGE_NONE _MOD_PROT(pgprot_user, L_PTE_XN | L_PTE_RDONLY)
#define PAGE_SHARED _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_WRITE)
#define PAGE_SHARED _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_XN)
#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_WRITE | L_PTE_EXEC)
#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_user, L_PTE_USER)
#define PAGE_COPY _MOD_PROT(pgprot_user, L_PTE_USER)
#define PAGE_COPY _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY | L_PTE_XN)
#define PAGE_COPY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_EXEC)
#define PAGE_COPY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY)
#define PAGE_READONLY _MOD_PROT(pgprot_user, L_PTE_USER)
#define PAGE_READONLY _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY | L_PTE_XN)
#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_EXEC)
#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_user, L_PTE_USER | L_PTE_RDONLY)
#define PAGE_KERNEL pgprot_kernel
#define PAGE_KERNEL _MOD_PROT(pgprot_kernel, L_PTE_XN)
#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_kernel, L_PTE_EXEC)
#define PAGE_KERNEL_EXEC pgprot_kernel
#define __PAGE_NONE __pgprot(_L_PTE_DEFAULT)
#define __PAGE_NONE __pgprot(_L_PTE_DEFAULT | L_PTE_RDONLY | L_PTE_XN)
#define __PAGE_SHARED __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_WRITE)
#define __PAGE_SHARED __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_XN)
#define __PAGE_SHARED_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_WRITE | L_PTE_EXEC)
#define __PAGE_SHARED_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER)
#define __PAGE_COPY __pgprot(_L_PTE_DEFAULT | L_PTE_USER)
#define __PAGE_COPY __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY | L_PTE_XN)
#define __PAGE_COPY_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_EXEC)
#define __PAGE_COPY_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY)
#define __PAGE_READONLY __pgprot(_L_PTE_DEFAULT | L_PTE_USER)
#define __PAGE_READONLY __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY | L_PTE_XN)
#define __PAGE_READONLY_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_EXEC)
#define __PAGE_READONLY_EXEC __pgprot(_L_PTE_DEFAULT | L_PTE_USER | L_PTE_RDONLY)
#define __pgprot_modify(prot,mask,bits) \
__pgprot((pgprot_val(prot) & ~(mask)) | (bits))
#define pgprot_noncached(prot) \
__pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED)
#define pgprot_writecombine(prot) \
__pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE)
#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
#define pgprot_dmacoherent(prot) \
__pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE | L_PTE_XN)
#define __HAVE_PHYS_MEM_ACCESS_PROT
struct
file
;
extern
pgprot_t
phys_mem_access_prot
(
struct
file
*
file
,
unsigned
long
pfn
,
unsigned
long
size
,
pgprot_t
vma_prot
);
#else
#define pgprot_dmacoherent(prot) \
__pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED | L_PTE_XN)
#endif
#endif
/* __ASSEMBLY__ */
#endif
/* __ASSEMBLY__ */
...
@@ -255,26 +280,84 @@ extern pgprot_t pgprot_kernel;
...
@@ -255,26 +280,84 @@ extern pgprot_t pgprot_kernel;
extern
struct
page
*
empty_zero_page
;
extern
struct
page
*
empty_zero_page
;
#define ZERO_PAGE(vaddr) (empty_zero_page)
#define ZERO_PAGE(vaddr) (empty_zero_page)
#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
#define pfn_pte(pfn,prot) (__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)))
#define pte_none(pte) (!pte_val(pte))
extern
pgd_t
swapper_pg_dir
[
PTRS_PER_PGD
];
#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0)
#define pte_page(pte) (pfn_to_page(pte_pfn(pte)))
/* to find an entry in a page-table-directory */
#define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr))
#define pgd_index(addr) ((addr) >> PGDIR_SHIFT)
#define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr))
/* 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)
/* 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
)
{
return
__va
(
pmd_val
(
pmd
)
&
PAGE_MASK
);
}
#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd)))
/* we don't need complex calculations here as the pmd is folded into the pgd */
#define pmd_addr_end(addr,end) (end)
#define pte_offset_map(dir,addr) (__pte_map(dir) + __pte_index(addr))
#define pte_unmap(pte) __pte_unmap(pte)
#ifndef CONFIG_HIGHPTE
#ifndef CONFIG_HIGHPTE
#define __pte_map(
dir) pmd_page_vaddr(*(dir
))
#define __pte_map(
pmd) pmd_page_vaddr(*(pmd
))
#define __pte_unmap(pte) do { } while (0)
#define __pte_unmap(pte) do { } while (0)
#else
#else
#define __pte_map(
dir) ((pte_t *)kmap_atomic(pmd_page(*(dir))) + PTRS_PER_PTE
)
#define __pte_map(
pmd) (pte_t *)kmap_atomic(pmd_page(*(pmd))
)
#define __pte_unmap(pte) kunmap_atomic(
(pte - PTRS_PER_PTE)
)
#define __pte_unmap(pte) kunmap_atomic(
pte
)
#endif
#endif
#define pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
#define pte_offset_kernel(pmd,addr) (pmd_page_vaddr(*(pmd)) + pte_index(addr))
#define pte_offset_map(pmd,addr) (__pte_map(pmd) + pte_index(addr))
#define pte_unmap(pte) __pte_unmap(pte)
#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
#define pfn_pte(pfn,prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
#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 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
#if __LINUX_ARM_ARCH__ < 6
static
inline
void
__sync_icache_dcache
(
pte_t
pteval
)
static
inline
void
__sync_icache_dcache
(
pte_t
pteval
)
...
@@ -295,15 +378,12 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
...
@@ -295,15 +378,12 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
}
}
}
}
/*
#define pte_none(pte) (!pte_val(pte))
* The following only work if pte_present() is true.
* Undefined behaviour if not..
*/
#define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT)
#define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT)
#define pte_write(pte) (
pte_val(pte) & L_PTE_WRITE
)
#define pte_write(pte) (
!(pte_val(pte) & L_PTE_RDONLY)
)
#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY)
#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY)
#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG)
#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG)
#define pte_exec(pte) (
pte_val(pte) & L_PTE_EXEC
)
#define pte_exec(pte) (
!(pte_val(pte) & L_PTE_XN)
)
#define pte_special(pte) (0)
#define pte_special(pte) (0)
#define pte_present_user(pte) \
#define pte_present_user(pte) \
...
@@ -313,8 +393,8 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
...
@@ -313,8 +393,8 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
#define PTE_BIT_FUNC(fn,op) \
#define PTE_BIT_FUNC(fn,op) \
static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
PTE_BIT_FUNC
(
wrprotect
,
&=
~
L_PTE_WRITE
);
PTE_BIT_FUNC
(
wrprotect
,
|=
L_PTE_RDONLY
);
PTE_BIT_FUNC
(
mkwrite
,
|=
L_PTE_WRITE
);
PTE_BIT_FUNC
(
mkwrite
,
&=
~
L_PTE_RDONLY
);
PTE_BIT_FUNC
(
mkclean
,
&=
~
L_PTE_DIRTY
);
PTE_BIT_FUNC
(
mkclean
,
&=
~
L_PTE_DIRTY
);
PTE_BIT_FUNC
(
mkdirty
,
|=
L_PTE_DIRTY
);
PTE_BIT_FUNC
(
mkdirty
,
|=
L_PTE_DIRTY
);
PTE_BIT_FUNC
(
mkold
,
&=
~
L_PTE_YOUNG
);
PTE_BIT_FUNC
(
mkold
,
&=
~
L_PTE_YOUNG
);
...
@@ -322,101 +402,13 @@ PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG);
...
@@ -322,101 +402,13 @@ PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG);
static
inline
pte_t
pte_mkspecial
(
pte_t
pte
)
{
return
pte
;
}
static
inline
pte_t
pte_mkspecial
(
pte_t
pte
)
{
return
pte
;
}
#define __pgprot_modify(prot,mask,bits) \
__pgprot((pgprot_val(prot) & ~(mask)) | (bits))
/*
* Mark the prot value as uncacheable and unbufferable.
*/
#define pgprot_noncached(prot) \
__pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED)
#define pgprot_writecombine(prot) \
__pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE)
#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
#define pgprot_dmacoherent(prot) \
__pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_BUFFERABLE)
#define __HAVE_PHYS_MEM_ACCESS_PROT
struct
file
;
extern
pgprot_t
phys_mem_access_prot
(
struct
file
*
file
,
unsigned
long
pfn
,
unsigned
long
size
,
pgprot_t
vma_prot
);
#else
#define pgprot_dmacoherent(prot) \
__pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_UNCACHED)
#endif
#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
)
{
unsigned
long
ptr
;
ptr
=
pmd_val
(
pmd
)
&
~
(
PTRS_PER_PTE
*
sizeof
(
void
*
)
-
1
);
ptr
+=
PTRS_PER_PTE
*
sizeof
(
void
*
);
return
__va
(
ptr
);
}
#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd)))
/* we don't need complex calculations here as the pmd is folded into the pgd */
#define pmd_addr_end(addr,end) (end)
/*
* Conversion functions: convert a page and protection to a page entry,
* and a page entry and page directory to the page they refer to.
*/
#define mk_pte(page,prot) pfn_pte(page_to_pfn(page),prot)
/*
* 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)
/* to find an entry in a page-table-directory */
#define pgd_index(addr) ((addr) >> PGDIR_SHIFT)
#define pgd_offset(mm, addr) ((mm)->pgd+pgd_index(addr))
/* to find an entry in a kernel page-table-directory */
#define pgd_offset_k(addr) pgd_offset(&init_mm, addr)
/* Find an entry in the second-level page table.. */
#define pmd_offset(dir, addr) ((pmd_t *)(dir))
/* Find an entry in the third-level page table.. */
#define __pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
static
inline
pte_t
pte_modify
(
pte_t
pte
,
pgprot_t
newprot
)
static
inline
pte_t
pte_modify
(
pte_t
pte
,
pgprot_t
newprot
)
{
{
const
unsigned
long
mask
=
L_PTE_EXEC
|
L_PTE_WRITE
|
L_PTE_USER
;
const
pteval_t
mask
=
L_PTE_XN
|
L_PTE_RDONLY
|
L_PTE_USER
;
pte_val
(
pte
)
=
(
pte_val
(
pte
)
&
~
mask
)
|
(
pgprot_val
(
newprot
)
&
mask
);
pte_val
(
pte
)
=
(
pte_val
(
pte
)
&
~
mask
)
|
(
pgprot_val
(
newprot
)
&
mask
);
return
pte
;
return
pte
;
}
}
extern
pgd_t
swapper_pg_dir
[
PTRS_PER_PGD
];
/*
/*
* Encode and decode a swap entry. Swap entries are stored in the Linux
* Encode and decode a swap entry. Swap entries are stored in the Linux
* page tables as follows:
* page tables as follows:
...
@@ -481,6 +473,9 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
...
@@ -481,6 +473,9 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
#define pgtable_cache_init() do { } while (0)
#define pgtable_cache_init() do { } while (0)
void
identity_mapping_add
(
pgd_t
*
,
unsigned
long
,
unsigned
long
);
void
identity_mapping_del
(
pgd_t
*
,
unsigned
long
,
unsigned
long
);
#endif
/* !__ASSEMBLY__ */
#endif
/* !__ASSEMBLY__ */
#endif
/* CONFIG_MMU */
#endif
/* CONFIG_MMU */
...
...
arch/arm/kernel/smp.c
View file @
28cdac66
...
@@ -55,42 +55,6 @@ enum ipi_msg_type {
...
@@ -55,42 +55,6 @@ enum ipi_msg_type {
IPI_CPU_STOP
,
IPI_CPU_STOP
,
};
};
static
inline
void
identity_mapping_add
(
pgd_t
*
pgd
,
unsigned
long
start
,
unsigned
long
end
)
{
unsigned
long
addr
,
prot
;
pmd_t
*
pmd
;
prot
=
PMD_TYPE_SECT
|
PMD_SECT_AP_WRITE
;
if
(
cpu_architecture
()
<=
CPU_ARCH_ARMv5TEJ
&&
!
cpu_is_xscale
())
prot
|=
PMD_BIT4
;
for
(
addr
=
start
&
PGDIR_MASK
;
addr
<
end
;)
{
pmd
=
pmd_offset
(
pgd
+
pgd_index
(
addr
),
addr
);
pmd
[
0
]
=
__pmd
(
addr
|
prot
);
addr
+=
SECTION_SIZE
;
pmd
[
1
]
=
__pmd
(
addr
|
prot
);
addr
+=
SECTION_SIZE
;
flush_pmd_entry
(
pmd
);
outer_clean_range
(
__pa
(
pmd
),
__pa
(
pmd
+
1
));
}
}
static
inline
void
identity_mapping_del
(
pgd_t
*
pgd
,
unsigned
long
start
,
unsigned
long
end
)
{
unsigned
long
addr
;
pmd_t
*
pmd
;
for
(
addr
=
start
&
PGDIR_MASK
;
addr
<
end
;
addr
+=
PGDIR_SIZE
)
{
pmd
=
pmd_offset
(
pgd
+
pgd_index
(
addr
),
addr
);
pmd
[
0
]
=
__pmd
(
0
);
pmd
[
1
]
=
__pmd
(
0
);
clean_pmd_entry
(
pmd
);
outer_clean_range
(
__pa
(
pmd
),
__pa
(
pmd
+
1
));
}
}
int
__cpuinit
__cpu_up
(
unsigned
int
cpu
)
int
__cpuinit
__cpu_up
(
unsigned
int
cpu
)
{
{
struct
cpuinfo_arm
*
ci
=
&
per_cpu
(
cpu_data
,
cpu
);
struct
cpuinfo_arm
*
ci
=
&
per_cpu
(
cpu_data
,
cpu
);
...
...
arch/arm/kernel/traps.c
View file @
28cdac66
...
@@ -710,19 +710,19 @@ void __readwrite_bug(const char *fn)
...
@@ -710,19 +710,19 @@ void __readwrite_bug(const char *fn)
}
}
EXPORT_SYMBOL
(
__readwrite_bug
);
EXPORT_SYMBOL
(
__readwrite_bug
);
void
__pte_error
(
const
char
*
file
,
int
line
,
unsigned
long
val
)
void
__pte_error
(
const
char
*
file
,
int
line
,
pte_t
pte
)
{
{
printk
(
"%s:%d: bad pte %08lx.
\n
"
,
file
,
line
,
val
);
printk
(
"%s:%d: bad pte %08lx.
\n
"
,
file
,
line
,
pte_val
(
pte
)
);
}
}
void
__pmd_error
(
const
char
*
file
,
int
line
,
unsigned
long
val
)
void
__pmd_error
(
const
char
*
file
,
int
line
,
pmd_t
pmd
)
{
{
printk
(
"%s:%d: bad pmd %08lx.
\n
"
,
file
,
line
,
val
);
printk
(
"%s:%d: bad pmd %08lx.
\n
"
,
file
,
line
,
pmd_val
(
pmd
)
);
}
}
void
__pgd_error
(
const
char
*
file
,
int
line
,
unsigned
long
val
)
void
__pgd_error
(
const
char
*
file
,
int
line
,
pgd_t
pgd
)
{
{
printk
(
"%s:%d: bad pgd %08lx.
\n
"
,
file
,
line
,
val
);
printk
(
"%s:%d: bad pgd %08lx.
\n
"
,
file
,
line
,
pgd_val
(
pgd
)
);
}
}
asmlinkage
void
__div0
(
void
)
asmlinkage
void
__div0
(
void
)
...
...
arch/arm/mm/Makefile
View file @
28cdac66
...
@@ -5,8 +5,8 @@
...
@@ -5,8 +5,8 @@
obj-y
:=
dma-mapping.o extable.o fault.o init.o
\
obj-y
:=
dma-mapping.o extable.o fault.o init.o
\
iomap.o
iomap.o
obj-$(CONFIG_MMU)
+=
fault-armv.o flush.o i
oremap.o m
map.o
\
obj-$(CONFIG_MMU)
+=
fault-armv.o flush.o i
dmap.o iore
map.o
\
pgd.o mmu.o vmregion.o
mmap.o
pgd.o mmu.o vmregion.o
ifneq
($(CONFIG_MMU),y)
ifneq
($(CONFIG_MMU),y)
obj-y
+=
nommu.o
obj-y
+=
nommu.o
...
...
arch/arm/mm/fault-armv.c
View file @
28cdac66
...
@@ -26,7 +26,7 @@
...
@@ -26,7 +26,7 @@
#include "mm.h"
#include "mm.h"
static
unsigned
long
shared_pte_mask
=
L_PTE_MT_BUFFERABLE
;
static
pteval_t
shared_pte_mask
=
L_PTE_MT_BUFFERABLE
;
#if __LINUX_ARM_ARCH__ < 6
#if __LINUX_ARM_ARCH__ < 6
/*
/*
...
...
arch/arm/mm/fault.c
View file @
28cdac66
...
@@ -108,7 +108,7 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
...
@@ -108,7 +108,7 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
pte
=
pte_offset_map
(
pmd
,
addr
);
pte
=
pte_offset_map
(
pmd
,
addr
);
printk
(
", *pte=%08lx"
,
pte_val
(
*
pte
));
printk
(
", *pte=%08lx"
,
pte_val
(
*
pte
));
printk
(
", *ppte=%08lx"
,
pte_val
(
pte
[
-
PTRS_PER_PTE
]));
printk
(
", *ppte=%08lx"
,
pte_val
(
pte
[
PTE_HWTABLE_PTRS
]));
pte_unmap
(
pte
);
pte_unmap
(
pte
);
}
while
(
0
);
}
while
(
0
);
...
...
arch/arm/mm/idmap.c
0 → 100644
View file @
28cdac66
#include <linux/kernel.h>
#include <asm/cputype.h>
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
static
void
idmap_add_pmd
(
pgd_t
*
pgd
,
unsigned
long
addr
,
unsigned
long
end
,
unsigned
long
prot
)
{
pmd_t
*
pmd
=
pmd_offset
(
pgd
,
addr
);
addr
=
(
addr
&
PMD_MASK
)
|
prot
;
pmd
[
0
]
=
__pmd
(
addr
);
addr
+=
SECTION_SIZE
;
pmd
[
1
]
=
__pmd
(
addr
);
flush_pmd_entry
(
pmd
);
}
void
identity_mapping_add
(
pgd_t
*
pgd
,
unsigned
long
addr
,
unsigned
long
end
)
{
unsigned
long
prot
,
next
;
prot
=
PMD_TYPE_SECT
|
PMD_SECT_AP_WRITE
;
if
(
cpu_architecture
()
<=
CPU_ARCH_ARMv5TEJ
&&
!
cpu_is_xscale
())
prot
|=
PMD_BIT4
;
pgd
+=
pgd_index
(
addr
);
do
{
next
=
pgd_addr_end
(
addr
,
end
);
idmap_add_pmd
(
pgd
,
addr
,
next
,
prot
);
}
while
(
pgd
++
,
addr
=
next
,
addr
!=
end
);
}
#ifdef CONFIG_SMP
static
void
idmap_del_pmd
(
pgd_t
*
pgd
,
unsigned
long
addr
,
unsigned
long
end
)
{
pmd_t
*
pmd
=
pmd_offset
(
pgd
,
addr
);
pmd_clear
(
pmd
);
}
void
identity_mapping_del
(
pgd_t
*
pgd
,
unsigned
long
addr
,
unsigned
long
end
)
{
unsigned
long
next
;
pgd
+=
pgd_index
(
addr
);
do
{
next
=
pgd_addr_end
(
addr
,
end
);
idmap_del_pmd
(
pgd
,
addr
,
next
);
}
while
(
pgd
++
,
addr
=
next
,
addr
!=
end
);
}
#endif
/*
* In order to soft-boot, we need to insert a 1:1 mapping in place of
* the user-mode pages. This will then ensure that we have predictable
* results when turning the mmu off
*/
void
setup_mm_for_reboot
(
char
mode
)
{
/*
* We need to access to user-mode page tables here. For kernel threads
* we don't have any user-mode mappings so we use the context that we
* "borrowed".
*/
identity_mapping_add
(
current
->
active_mm
->
pgd
,
0
,
TASK_SIZE
);
local_flush_tlb_all
();
}
arch/arm/mm/mm.h
View file @
28cdac66
...
@@ -16,7 +16,7 @@ static inline pmd_t *pmd_off_k(unsigned long virt)
...
@@ -16,7 +16,7 @@ static inline pmd_t *pmd_off_k(unsigned long virt)
}
}
struct
mem_type
{
struct
mem_type
{
unsigned
in
t
prot_pte
;
pteval_
t
prot_pte
;
unsigned
int
prot_l1
;
unsigned
int
prot_l1
;
unsigned
int
prot_sect
;
unsigned
int
prot_sect
;
unsigned
int
domain
;
unsigned
int
domain
;
...
...
arch/arm/mm/mmu.c
View file @
28cdac66
...
@@ -63,7 +63,7 @@ struct cachepolicy {
...
@@ -63,7 +63,7 @@ struct cachepolicy {
const
char
policy
[
16
];
const
char
policy
[
16
];
unsigned
int
cr_mask
;
unsigned
int
cr_mask
;
unsigned
int
pmd
;
unsigned
int
pmd
;
unsigned
in
t
pte
;
pteval_
t
pte
;
};
};
static
struct
cachepolicy
cache_policies
[]
__initdata
=
{
static
struct
cachepolicy
cache_policies
[]
__initdata
=
{
...
@@ -191,7 +191,7 @@ void adjust_cr(unsigned long mask, unsigned long set)
...
@@ -191,7 +191,7 @@ void adjust_cr(unsigned long mask, unsigned long set)
}
}
#endif
#endif
#define PROT_PTE_DEVICE L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_
WRITE
#define PROT_PTE_DEVICE L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_
XN
#define PROT_SECT_DEVICE PMD_TYPE_SECT|PMD_SECT_AP_WRITE
#define PROT_SECT_DEVICE PMD_TYPE_SECT|PMD_SECT_AP_WRITE
static
struct
mem_type
mem_types
[]
=
{
static
struct
mem_type
mem_types
[]
=
{
...
@@ -236,19 +236,18 @@ static struct mem_type mem_types[] = {
...
@@ -236,19 +236,18 @@ static struct mem_type mem_types[] = {
},
},
[
MT_LOW_VECTORS
]
=
{
[
MT_LOW_VECTORS
]
=
{
.
prot_pte
=
L_PTE_PRESENT
|
L_PTE_YOUNG
|
L_PTE_DIRTY
|
.
prot_pte
=
L_PTE_PRESENT
|
L_PTE_YOUNG
|
L_PTE_DIRTY
|
L_PTE_
EXEC
,
L_PTE_
RDONLY
,
.
prot_l1
=
PMD_TYPE_TABLE
,
.
prot_l1
=
PMD_TYPE_TABLE
,
.
domain
=
DOMAIN_USER
,
.
domain
=
DOMAIN_USER
,
},
},
[
MT_HIGH_VECTORS
]
=
{
[
MT_HIGH_VECTORS
]
=
{
.
prot_pte
=
L_PTE_PRESENT
|
L_PTE_YOUNG
|
L_PTE_DIRTY
|
.
prot_pte
=
L_PTE_PRESENT
|
L_PTE_YOUNG
|
L_PTE_DIRTY
|
L_PTE_USER
|
L_PTE_
EXEC
,
L_PTE_USER
|
L_PTE_
RDONLY
,
.
prot_l1
=
PMD_TYPE_TABLE
,
.
prot_l1
=
PMD_TYPE_TABLE
,
.
domain
=
DOMAIN_USER
,
.
domain
=
DOMAIN_USER
,
},
},
[
MT_MEMORY
]
=
{
[
MT_MEMORY
]
=
{
.
prot_pte
=
L_PTE_PRESENT
|
L_PTE_YOUNG
|
L_PTE_DIRTY
|
.
prot_pte
=
L_PTE_PRESENT
|
L_PTE_YOUNG
|
L_PTE_DIRTY
,
L_PTE_WRITE
|
L_PTE_EXEC
,
.
prot_l1
=
PMD_TYPE_TABLE
,
.
prot_l1
=
PMD_TYPE_TABLE
,
.
prot_sect
=
PMD_TYPE_SECT
|
PMD_SECT_AP_WRITE
,
.
prot_sect
=
PMD_TYPE_SECT
|
PMD_SECT_AP_WRITE
,
.
domain
=
DOMAIN_KERNEL
,
.
domain
=
DOMAIN_KERNEL
,
...
@@ -259,21 +258,20 @@ static struct mem_type mem_types[] = {
...
@@ -259,21 +258,20 @@ static struct mem_type mem_types[] = {
},
},
[
MT_MEMORY_NONCACHED
]
=
{
[
MT_MEMORY_NONCACHED
]
=
{
.
prot_pte
=
L_PTE_PRESENT
|
L_PTE_YOUNG
|
L_PTE_DIRTY
|
.
prot_pte
=
L_PTE_PRESENT
|
L_PTE_YOUNG
|
L_PTE_DIRTY
|
L_PTE_
WRITE
|
L_PTE_EXEC
|
L_PTE_
MT_BUFFERABLE
,
L_PTE_MT_BUFFERABLE
,
.
prot_l1
=
PMD_TYPE_TABLE
,
.
prot_l1
=
PMD_TYPE_TABLE
,
.
prot_sect
=
PMD_TYPE_SECT
|
PMD_SECT_AP_WRITE
,
.
prot_sect
=
PMD_TYPE_SECT
|
PMD_SECT_AP_WRITE
,
.
domain
=
DOMAIN_KERNEL
,
.
domain
=
DOMAIN_KERNEL
,
},
},
[
MT_MEMORY_DTCM
]
=
{
[
MT_MEMORY_DTCM
]
=
{
.
prot_pte
=
L_PTE_PRESENT
|
L_PTE_YOUNG
|
L_PTE_DIRTY
|
.
prot_pte
=
L_PTE_PRESENT
|
L_PTE_YOUNG
|
L_PTE_DIRTY
|
L_PTE_
WRITE
,
L_PTE_
XN
,
.
prot_l1
=
PMD_TYPE_TABLE
,
.
prot_l1
=
PMD_TYPE_TABLE
,
.
prot_sect
=
PMD_TYPE_SECT
|
PMD_SECT_XN
,
.
prot_sect
=
PMD_TYPE_SECT
|
PMD_SECT_XN
,
.
domain
=
DOMAIN_KERNEL
,
.
domain
=
DOMAIN_KERNEL
,
},
},
[
MT_MEMORY_ITCM
]
=
{
[
MT_MEMORY_ITCM
]
=
{
.
prot_pte
=
L_PTE_PRESENT
|
L_PTE_YOUNG
|
L_PTE_DIRTY
|
.
prot_pte
=
L_PTE_PRESENT
|
L_PTE_YOUNG
|
L_PTE_DIRTY
,
L_PTE_WRITE
|
L_PTE_EXEC
,
.
prot_l1
=
PMD_TYPE_TABLE
,
.
prot_l1
=
PMD_TYPE_TABLE
,
.
domain
=
DOMAIN_KERNEL
,
.
domain
=
DOMAIN_KERNEL
,
},
},
...
@@ -480,7 +478,7 @@ static void __init build_mem_type_table(void)
...
@@ -480,7 +478,7 @@ static void __init build_mem_type_table(void)
pgprot_user
=
__pgprot
(
L_PTE_PRESENT
|
L_PTE_YOUNG
|
user_pgprot
);
pgprot_user
=
__pgprot
(
L_PTE_PRESENT
|
L_PTE_YOUNG
|
user_pgprot
);
pgprot_kernel
=
__pgprot
(
L_PTE_PRESENT
|
L_PTE_YOUNG
|
pgprot_kernel
=
__pgprot
(
L_PTE_PRESENT
|
L_PTE_YOUNG
|
L_PTE_DIRTY
|
L_PTE_WRITE
|
kern_pgprot
);
L_PTE_DIRTY
|
kern_pgprot
);
mem_types
[
MT_LOW_VECTORS
].
prot_l1
|=
ecc_mask
;
mem_types
[
MT_LOW_VECTORS
].
prot_l1
|=
ecc_mask
;
mem_types
[
MT_HIGH_VECTORS
].
prot_l1
|=
ecc_mask
;
mem_types
[
MT_HIGH_VECTORS
].
prot_l1
|=
ecc_mask
;
...
@@ -536,7 +534,7 @@ static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned l
...
@@ -536,7 +534,7 @@ static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned l
{
{
if
(
pmd_none
(
*
pmd
))
{
if
(
pmd_none
(
*
pmd
))
{
pte_t
*
pte
=
early_alloc
(
2
*
PTRS_PER_PTE
*
sizeof
(
pte_t
));
pte_t
*
pte
=
early_alloc
(
2
*
PTRS_PER_PTE
*
sizeof
(
pte_t
));
__pmd_populate
(
pmd
,
__pa
(
pte
)
|
prot
);
__pmd_populate
(
pmd
,
__pa
(
pte
)
,
prot
);
}
}
BUG_ON
(
pmd_bad
(
*
pmd
));
BUG_ON
(
pmd_bad
(
*
pmd
));
return
pte_offset_kernel
(
pmd
,
addr
);
return
pte_offset_kernel
(
pmd
,
addr
);
...
@@ -554,7 +552,7 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
...
@@ -554,7 +552,7 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
}
}
static
void
__init
alloc_init_section
(
pgd_t
*
pgd
,
unsigned
long
addr
,
static
void
__init
alloc_init_section
(
pgd_t
*
pgd
,
unsigned
long
addr
,
unsigned
long
end
,
unsigned
long
phys
,
unsigned
long
end
,
phys_addr_t
phys
,
const
struct
mem_type
*
type
)
const
struct
mem_type
*
type
)
{
{
pmd_t
*
pmd
=
pmd_offset
(
pgd
,
addr
);
pmd_t
*
pmd
=
pmd_offset
(
pgd
,
addr
);
...
@@ -589,7 +587,8 @@ static void __init alloc_init_section(pgd_t *pgd, unsigned long addr,
...
@@ -589,7 +587,8 @@ static void __init alloc_init_section(pgd_t *pgd, unsigned long addr,
static
void
__init
create_36bit_mapping
(
struct
map_desc
*
md
,
static
void
__init
create_36bit_mapping
(
struct
map_desc
*
md
,
const
struct
mem_type
*
type
)
const
struct
mem_type
*
type
)
{
{
unsigned
long
phys
,
addr
,
length
,
end
;
unsigned
long
addr
,
length
,
end
;
phys_addr_t
phys
;
pgd_t
*
pgd
;
pgd_t
*
pgd
;
addr
=
md
->
virtual
;
addr
=
md
->
virtual
;
...
@@ -1044,38 +1043,3 @@ void __init paging_init(struct machine_desc *mdesc)
...
@@ -1044,38 +1043,3 @@ void __init paging_init(struct machine_desc *mdesc)
empty_zero_page
=
virt_to_page
(
zero_page
);
empty_zero_page
=
virt_to_page
(
zero_page
);
__flush_dcache_page
(
NULL
,
empty_zero_page
);
__flush_dcache_page
(
NULL
,
empty_zero_page
);
}
}
/*
* In order to soft-boot, we need to insert a 1:1 mapping in place of
* the user-mode pages. This will then ensure that we have predictable
* results when turning the mmu off
*/
void
setup_mm_for_reboot
(
char
mode
)
{
unsigned
long
base_pmdval
;
pgd_t
*
pgd
;
int
i
;
/*
* We need to access to user-mode page tables here. For kernel threads
* we don't have any user-mode mappings so we use the context that we
* "borrowed".
*/
pgd
=
current
->
active_mm
->
pgd
;
base_pmdval
=
PMD_SECT_AP_WRITE
|
PMD_SECT_AP_READ
|
PMD_TYPE_SECT
;
if
(
cpu_architecture
()
<=
CPU_ARCH_ARMv5TEJ
&&
!
cpu_is_xscale
())
base_pmdval
|=
PMD_BIT4
;
for
(
i
=
0
;
i
<
FIRST_USER_PGD_NR
+
USER_PTRS_PER_PGD
;
i
++
,
pgd
++
)
{
unsigned
long
pmdval
=
(
i
<<
PGDIR_SHIFT
)
|
base_pmdval
;
pmd_t
*
pmd
;
pmd
=
pmd_off
(
pgd
,
i
<<
PGDIR_SHIFT
);
pmd
[
0
]
=
__pmd
(
pmdval
);
pmd
[
1
]
=
__pmd
(
pmdval
+
(
1
<<
(
PGDIR_SHIFT
-
1
)));
flush_pmd_entry
(
pmd
);
}
local_flush_tlb_all
();
}
arch/arm/mm/pgd.c
View file @
28cdac66
...
@@ -17,12 +17,10 @@
...
@@ -17,12 +17,10 @@
#include "mm.h"
#include "mm.h"
#define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD)
/*
/*
* need to get a 16k page for level 1
* need to get a 16k page for level 1
*/
*/
pgd_t
*
get_pgd_slow
(
struct
mm_struct
*
mm
)
pgd_t
*
pgd_alloc
(
struct
mm_struct
*
mm
)
{
{
pgd_t
*
new_pgd
,
*
init_pgd
;
pgd_t
*
new_pgd
,
*
init_pgd
;
pmd_t
*
new_pmd
,
*
init_pmd
;
pmd_t
*
new_pmd
,
*
init_pmd
;
...
@@ -32,14 +30,14 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
...
@@ -32,14 +30,14 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
if
(
!
new_pgd
)
if
(
!
new_pgd
)
goto
no_pgd
;
goto
no_pgd
;
memset
(
new_pgd
,
0
,
FIRST_KERNEL_PGD_NR
*
sizeof
(
pgd_t
));
memset
(
new_pgd
,
0
,
USER_PTRS_PER_PGD
*
sizeof
(
pgd_t
));
/*
/*
* Copy over the kernel and IO PGD entries
* Copy over the kernel and IO PGD entries
*/
*/
init_pgd
=
pgd_offset_k
(
0
);
init_pgd
=
pgd_offset_k
(
0
);
memcpy
(
new_pgd
+
FIRST_KERNEL_PGD_NR
,
init_pgd
+
FIRST_KERNEL_PGD_NR
,
memcpy
(
new_pgd
+
USER_PTRS_PER_PGD
,
init_pgd
+
USER_PTRS_PER_PGD
,
(
PTRS_PER_PGD
-
FIRST_KERNEL_PGD_NR
)
*
sizeof
(
pgd_t
));
(
PTRS_PER_PGD
-
USER_PTRS_PER_PGD
)
*
sizeof
(
pgd_t
));
clean_dcache_area
(
new_pgd
,
PTRS_PER_PGD
*
sizeof
(
pgd_t
));
clean_dcache_area
(
new_pgd
,
PTRS_PER_PGD
*
sizeof
(
pgd_t
));
...
@@ -73,28 +71,29 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
...
@@ -73,28 +71,29 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
return
NULL
;
return
NULL
;
}
}
void
free_pgd_slow
(
struct
mm_struct
*
mm
,
pgd_t
*
pgd
)
void
pgd_free
(
struct
mm_struct
*
mm
,
pgd_t
*
pgd_base
)
{
{
pgd_t
*
pgd
;
pmd_t
*
pmd
;
pmd_t
*
pmd
;
pgtable_t
pte
;
pgtable_t
pte
;
if
(
!
pgd
)
if
(
!
pgd
_base
)
return
;
return
;
/* pgd is always present and good */
pgd
=
pgd_base
+
pgd_index
(
0
);
pmd
=
pmd_off
(
pgd
,
0
);
if
(
pgd_none_or_clear_bad
(
pgd
))
if
(
pmd_none
(
*
pmd
))
goto
no_pgd
;
goto
free
;
if
(
pmd_bad
(
*
pmd
))
{
pmd
=
pmd_offset
(
pgd
,
0
);
pmd_ERROR
(
*
pmd
);
if
(
pmd_none_or_clear_bad
(
pmd
))
pmd_clear
(
pmd
);
goto
no_pmd
;
goto
free
;
}
pte
=
pmd_pgtable
(
*
pmd
);
pte
=
pmd_pgtable
(
*
pmd
);
pmd_clear
(
pmd
);
pmd_clear
(
pmd
);
pte_free
(
mm
,
pte
);
pte_free
(
mm
,
pte
);
no_pmd:
pgd_clear
(
pgd
);
pmd_free
(
mm
,
pmd
);
pmd_free
(
mm
,
pmd
);
free
:
no_pgd
:
free_pages
((
unsigned
long
)
pgd
,
2
);
free_pages
((
unsigned
long
)
pgd
_base
,
2
);
}
}
arch/arm/mm/proc-macros.S
View file @
28cdac66
...
@@ -91,7 +91,7 @@
...
@@ -91,7 +91,7 @@
#if L_PTE_SHARED != PTE_EXT_SHARED
#if L_PTE_SHARED != PTE_EXT_SHARED
#error PTE shared bit mismatch
#error PTE shared bit mismatch
#endif
#endif
#if (L_PTE_
EXEC+L_PTE_USER+L_PTE_WRITE
+L_PTE_DIRTY+L_PTE_YOUNG+\
#if (L_PTE_
XN+L_PTE_USER+L_PTE_RDONLY
+L_PTE_DIRTY+L_PTE_YOUNG+\
L_PTE_FILE
+
L_PTE_PRESENT
)
>
L_PTE_SHARED
L_PTE_FILE
+
L_PTE_PRESENT
)
>
L_PTE_SHARED
#error Invalid Linux PTE bit settings
#error Invalid Linux PTE bit settings
#endif
#endif
...
@@ -135,7 +135,7 @@
...
@@ -135,7 +135,7 @@
.
endm
.
endm
.
macro
armv6_set_pte_ext
pfx
.
macro
armv6_set_pte_ext
pfx
str
r1
,
[
r0
],
#
-
2048
@
linux
version
str
r1
,
[
r0
],
#
2048
@
linux
version
bic
r3
,
r1
,
#
0x000003fc
bic
r3
,
r1
,
#
0x000003fc
bic
r3
,
r3
,
#
PTE_TYPE_MASK
bic
r3
,
r3
,
#
PTE_TYPE_MASK
...
@@ -146,9 +146,9 @@
...
@@ -146,9 +146,9 @@
and
r2
,
r1
,
#
L_PTE_MT_MASK
and
r2
,
r1
,
#
L_PTE_MT_MASK
ldr
r2
,
[
ip
,
r2
]
ldr
r2
,
[
ip
,
r2
]
tst
r1
,
#
L_PTE_WRITE
eor
r1
,
r1
,
#
L_PTE_DIRTY
tst
ne
r1
,
#
L_PTE_DIRT
Y
tst
r1
,
#
L_PTE_DIRTY
|
L_PTE_RDONL
Y
orr
eq
r3
,
r3
,
#
PTE_EXT_APX
orr
ne
r3
,
r3
,
#
PTE_EXT_APX
tst
r1
,
#
L_PTE_USER
tst
r1
,
#
L_PTE_USER
orrne
r3
,
r3
,
#
PTE_EXT_AP1
orrne
r3
,
r3
,
#
PTE_EXT_AP1
...
@@ -158,8 +158,8 @@
...
@@ -158,8 +158,8 @@
bicne
r3
,
r3
,
#
PTE_EXT_APX
|
PTE_EXT_AP0
bicne
r3
,
r3
,
#
PTE_EXT_APX
|
PTE_EXT_AP0
#endif
#endif
tst
r1
,
#
L_PTE_
EXEC
tst
r1
,
#
L_PTE_
XN
orr
eq
r3
,
r3
,
#
PTE_EXT_XN
orr
ne
r3
,
r3
,
#
PTE_EXT_XN
orr
r3
,
r3
,
r2
orr
r3
,
r3
,
r2
...
@@ -187,9 +187,9 @@
...
@@ -187,9 +187,9 @@
*
1111
0xff
r
/
w
r
/
w
*
1111
0xff
r
/
w
r
/
w
*/
*/
.
macro
armv3_set_pte_ext
wc_disable
=
1
.
macro
armv3_set_pte_ext
wc_disable
=
1
str
r1
,
[
r0
],
#
-
2048
@
linux
version
str
r1
,
[
r0
],
#
2048
@
linux
version
eor
r3
,
r1
,
#
L_PTE_PRESENT
| L_PTE_YOUNG |
L_PTE_
WRITE
|
L_PTE_
DIRTY
eor
r3
,
r1
,
#
L_PTE_PRESENT
| L_PTE_YOUNG |
L_PTE_DIRTY
bic
r2
,
r1
,
#
PTE_SMALL_AP_MASK
@
keep
C
,
B
bits
bic
r2
,
r1
,
#
PTE_SMALL_AP_MASK
@
keep
C
,
B
bits
bic
r2
,
r2
,
#
PTE_TYPE_MASK
bic
r2
,
r2
,
#
PTE_TYPE_MASK
...
@@ -198,7 +198,7 @@
...
@@ -198,7 +198,7 @@
tst
r3
,
#
L_PTE_USER
@
user
?
tst
r3
,
#
L_PTE_USER
@
user
?
orrne
r2
,
r2
,
#
PTE_SMALL_AP_URO_SRW
orrne
r2
,
r2
,
#
PTE_SMALL_AP_URO_SRW
tst
r3
,
#
L_PTE_
WRITE
|
L_PTE_DIRTY
@
write
and
dirty
?
tst
r3
,
#
L_PTE_
RDONLY
|
L_PTE_DIRTY
@
write
and
dirty
?
orreq
r2
,
r2
,
#
PTE_SMALL_AP_UNO_SRW
orreq
r2
,
r2
,
#
PTE_SMALL_AP_UNO_SRW
tst
r3
,
#
L_PTE_PRESENT
|
L_PTE_YOUNG
@
present
and
young
?
tst
r3
,
#
L_PTE_PRESENT
|
L_PTE_YOUNG
@
present
and
young
?
...
@@ -210,7 +210,7 @@
...
@@ -210,7 +210,7 @@
bicne
r2
,
r2
,
#
PTE_BUFFERABLE
bicne
r2
,
r2
,
#
PTE_BUFFERABLE
#endif
#endif
.
endif
.
endif
str
r2
,
[
r0
]
@
hardware
version
str
r2
,
[
r0
]
@
hardware
version
.
endm
.
endm
...
@@ -230,9 +230,9 @@
...
@@ -230,9 +230,9 @@
*
1111
11
r
/
w
r
/
w
*
1111
11
r
/
w
r
/
w
*/
*/
.
macro
xscale_set_pte_ext_prologue
.
macro
xscale_set_pte_ext_prologue
str
r1
,
[
r0
]
,
#-
2048
@
linux
version
str
r1
,
[
r0
]
@
linux
version
eor
r3
,
r1
,
#
L_PTE_PRESENT
| L_PTE_YOUNG |
L_PTE_
WRITE
|
L_PTE_
DIRTY
eor
r3
,
r1
,
#
L_PTE_PRESENT
| L_PTE_YOUNG |
L_PTE_DIRTY
bic
r2
,
r1
,
#
PTE_SMALL_AP_MASK
@
keep
C
,
B
bits
bic
r2
,
r1
,
#
PTE_SMALL_AP_MASK
@
keep
C
,
B
bits
orr
r2
,
r2
,
#
PTE_TYPE_EXT
@
extended
page
orr
r2
,
r2
,
#
PTE_TYPE_EXT
@
extended
page
...
@@ -240,7 +240,7 @@
...
@@ -240,7 +240,7 @@
tst
r3
,
#
L_PTE_USER
@
user
?
tst
r3
,
#
L_PTE_USER
@
user
?
orrne
r2
,
r2
,
#
PTE_EXT_AP_URO_SRW
@
yes
->
user
r
/
o
,
system
r
/
w
orrne
r2
,
r2
,
#
PTE_EXT_AP_URO_SRW
@
yes
->
user
r
/
o
,
system
r
/
w
tst
r3
,
#
L_PTE_
WRITE
|
L_PTE_DIRTY
@
write
and
dirty
?
tst
r3
,
#
L_PTE_
RDONLY
|
L_PTE_DIRTY
@
write
and
dirty
?
orreq
r2
,
r2
,
#
PTE_EXT_AP_UNO_SRW
@
yes
->
user
n
/
a
,
system
r
/
w
orreq
r2
,
r2
,
#
PTE_EXT_AP_UNO_SRW
@
yes
->
user
n
/
a
,
system
r
/
w
@
combined
with
user
->
user
r
/
w
@
combined
with
user
->
user
r
/
w
.
endm
.
endm
...
@@ -249,7 +249,7 @@
...
@@ -249,7 +249,7 @@
tst
r3
,
#
L_PTE_PRESENT
|
L_PTE_YOUNG
@
present
and
young
?
tst
r3
,
#
L_PTE_PRESENT
|
L_PTE_YOUNG
@
present
and
young
?
movne
r2
,
#
0
@
no
->
fault
movne
r2
,
#
0
@
no
->
fault
str
r2
,
[
r0
]
@
hardware
version
str
r2
,
[
r0
,
#
2048
]!
@
hardware
version
mov
ip
,
#
0
mov
ip
,
#
0
mcr
p15
,
0
,
r0
,
c7
,
c10
,
1
@
clean
L1
D
line
mcr
p15
,
0
,
r0
,
c7
,
c10
,
1
@
clean
L1
D
line
mcr
p15
,
0
,
ip
,
c7
,
c10
,
4
@
data
write
barrier
mcr
p15
,
0
,
ip
,
c7
,
c10
,
4
@
data
write
barrier
...
...
arch/arm/mm/proc-v7.S
View file @
28cdac66
...
@@ -124,15 +124,13 @@ ENDPROC(cpu_v7_switch_mm)
...
@@ -124,15 +124,13 @@ ENDPROC(cpu_v7_switch_mm)
*
Set
a
level
2
translation
table
entry
.
*
Set
a
level
2
translation
table
entry
.
*
*
*
-
ptep
-
pointer
to
level
2
translation
table
entry
*
-
ptep
-
pointer
to
level
2
translation
table
entry
*
(
hardware
version
is
stored
at
-
1024
bytes
)
*
(
hardware
version
is
stored
at
+
2048
bytes
)
*
-
pte
-
PTE
value
to
store
*
-
pte
-
PTE
value
to
store
*
-
ext
-
value
for
extended
PTE
bits
*
-
ext
-
value
for
extended
PTE
bits
*/
*/
ENTRY
(
cpu_v7_set_pte_ext
)
ENTRY
(
cpu_v7_set_pte_ext
)
#ifdef CONFIG_MMU
#ifdef CONFIG_MMU
ARM
(
str
r1
,
[
r0
],
#-
2048
)
@
linux
version
str
r1
,
[
r0
]
@
linux
version
THUMB
(
str
r1
,
[
r0
]
)
@
linux
version
THUMB
(
sub
r0
,
r0
,
#
2048
)
bic
r3
,
r1
,
#
0x000003f0
bic
r3
,
r1
,
#
0x000003f0
bic
r3
,
r3
,
#
PTE_TYPE_MASK
bic
r3
,
r3
,
#
PTE_TYPE_MASK
...
@@ -142,9 +140,9 @@ ENTRY(cpu_v7_set_pte_ext)
...
@@ -142,9 +140,9 @@ ENTRY(cpu_v7_set_pte_ext)
tst
r1
,
#
1
<<
4
tst
r1
,
#
1
<<
4
orrne
r3
,
r3
,
#
PTE_EXT_TEX
(
1
)
orrne
r3
,
r3
,
#
PTE_EXT_TEX
(
1
)
tst
r1
,
#
L_PTE_WRITE
eor
r1
,
r1
,
#
L_PTE_DIRTY
tst
ne
r1
,
#
L_PTE_DIRTY
tst
r1
,
#
L_PTE_RDONLY
|
L_PTE_DIRTY
orr
eq
r3
,
r3
,
#
PTE_EXT_APX
orr
ne
r3
,
r3
,
#
PTE_EXT_APX
tst
r1
,
#
L_PTE_USER
tst
r1
,
#
L_PTE_USER
orrne
r3
,
r3
,
#
PTE_EXT_AP1
orrne
r3
,
r3
,
#
PTE_EXT_AP1
...
@@ -154,14 +152,14 @@ ENTRY(cpu_v7_set_pte_ext)
...
@@ -154,14 +152,14 @@ ENTRY(cpu_v7_set_pte_ext)
bicne
r3
,
r3
,
#
PTE_EXT_APX
|
PTE_EXT_AP0
bicne
r3
,
r3
,
#
PTE_EXT_APX
|
PTE_EXT_AP0
#endif
#endif
tst
r1
,
#
L_PTE_
EXEC
tst
r1
,
#
L_PTE_
XN
orr
eq
r3
,
r3
,
#
PTE_EXT_XN
orr
ne
r3
,
r3
,
#
PTE_EXT_XN
tst
r1
,
#
L_PTE_YOUNG
tst
r1
,
#
L_PTE_YOUNG
tstne
r1
,
#
L_PTE_PRESENT
tstne
r1
,
#
L_PTE_PRESENT
moveq
r3
,
#
0
moveq
r3
,
#
0
str
r3
,
[
r0
]
str
r3
,
[
r0
,
#
2048
]!
mcr
p15
,
0
,
r0
,
c7
,
c10
,
1
@
flush_pte
mcr
p15
,
0
,
r0
,
c7
,
c10
,
1
@
flush_pte
#endif
#endif
mov
pc
,
lr
mov
pc
,
lr
...
...
arch/arm/mm/proc-xscale.S
View file @
28cdac66
...
@@ -500,8 +500,8 @@ ENTRY(cpu_xscale_set_pte_ext)
...
@@ -500,8 +500,8 @@ ENTRY(cpu_xscale_set_pte_ext)
@
@
@
Erratum
40
:
must
set
memory
to
write
-
through
for
user
read
-
only
pages
@
Erratum
40
:
must
set
memory
to
write
-
through
for
user
read
-
only
pages
@
@
and
ip
,
r1
,
#(
L_PTE_MT_MASK
| L_PTE_USER |
L_PTE_
WRITE
)
&
~
(
4
<<
2
)
and
ip
,
r1
,
#(
L_PTE_MT_MASK
| L_PTE_USER |
L_PTE_
RDONLY
)
&
~
(
4
<<
2
)
teq
ip
,
#
L_PTE_MT_WRITEBACK
|
L_PTE_USER
teq
ip
,
#
L_PTE_MT_WRITEBACK
| L_PTE_USER
|
L_PTE_RDONLY
moveq
r1
,
#
L_PTE_MT_WRITETHROUGH
moveq
r1
,
#
L_PTE_MT_WRITETHROUGH
and
r1
,
r1
,
#
L_PTE_MT_MASK
and
r1
,
r1
,
#
L_PTE_MT_MASK
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment