99,11 → 99,63 |
#define PTE_GET_FRAME_ARCH(pte) ( ((pte_level1_t *)(pte))->frame_base_addr << FRAME_WIDTH) |
/* pte should point into ptl3 */ |
#define PTE_WRITABLE_ARCH(pte) ( ((pte_level1_t *)(pte))->access_permission_0 == PTE_AP_USER_RW_KERNEL_RW ) |
|
#define PTE_EXECUTABLE_ARCH(pte) 1 |
|
#ifndef __ASM__ |
|
/** Level 0 page table entry. */ |
typedef struct { |
/* 01b for coarse tables, see below for details */ |
unsigned descriptor_type : 2; |
unsigned impl_specific : 3; |
unsigned domain : 4; |
unsigned should_be_zero : 1; |
/* Pointer to the coarse 2nd level page table (holding entries for small (4KB) |
* or large (64KB) pages. ARM also supports fine 2nd level page tables that |
* may hold even tiny pages (1KB) but they are bigger (4KB per table in comparison |
* with 1KB per the coarse table) |
*/ |
unsigned coarse_table_addr : 22; |
} __attribute__ ((packed)) pte_level0_t; |
|
/** Level 1 page table entry (small (4KB) pages used) */ |
typedef struct { |
/* 0b10 for small pages */ |
unsigned descriptor_type : 2; |
unsigned bufferable : 1; |
unsigned cacheable : 1; |
/* access permissions for each of 4 subparts of a page |
* (for each 1KB when small pages used */ |
unsigned access_permission_0 : 2; |
unsigned access_permission_1 : 2; |
unsigned access_permission_2 : 2; |
unsigned access_permission_3 : 2; |
unsigned frame_base_addr : 20; |
} __attribute__ ((packed)) pte_level1_t; |
|
|
/* Level 1 page tables access permissions */ |
|
/** User mode: no access, privileged mode: no access */ |
#define PTE_AP_USER_NO_KERNEL_NO 0 |
/** User mode: no access, privileged mode: read/write */ |
#define PTE_AP_USER_NO_KERNEL_RW 1 |
/** User mode: read only, privileged mode: read/write */ |
#define PTE_AP_USER_RO_KERNEL_RW 2 |
/** User mode: read/write, privileged mode: read/write */ |
#define PTE_AP_USER_RW_KERNEL_RW 3 |
|
|
/* pte_level0_t and pte_level1_t descriptor_type flags */ |
|
/** pte_level0_t and pte_level1_t "not present" flag (used in descriptor_type) */ |
#define PTE_DESCRIPTOR_NOT_PRESENT 0 |
/** pte_level0_t coarse page table flag (used in descriptor_type) */ |
#define PTE_DESCRIPTOR_COARSE_TABLE 1 |
/** pte_level1_t small page table flag (used in descriptor type) */ |
#define PTE_DESCRIPTOR_SMALL_PAGE 2 |
|
|
/** |
* Sets the address of level 0 page table. |
* |
111,11 → 163,11 |
*/ |
static inline void set_ptl0_addr( pte_level0_t* pt) |
{ |
asm volatile ( "mcr p15, 0, %0, c2, c0, 0 \n" |
asm volatile ( |
"mcr p15, 0, %0, c2, c0, 0 \n" |
: |
: "r"(pt) |
); |
|
} |
|
/** Returns level 0 page table entry flags. |