SELFOUR-501: x86 - Remove PAE support
This commit is contained in:
parent
135ab71dff
commit
3e57e647e9
15 changed files with 14 additions and 697 deletions
|
|
@ -29,11 +29,7 @@ endpoint_ptr_get_epQueue_tail_fp(endpoint_t *ep_ptr)
|
|||
static inline vspace_root_t *
|
||||
cap_vtable_cap_get_vspace_root_fp(cap_t vtable_cap)
|
||||
{
|
||||
#if defined(CONFIG_PAE_PAGING)
|
||||
return PDPTE_PTR(cap_pdpt_cap_get_capPDPTBasePtr(vtable_cap));
|
||||
#else
|
||||
return PDE_PTR(cap_page_directory_cap_get_capPDBasePtr(vtable_cap));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void FORCE_INLINE
|
||||
|
|
@ -72,11 +68,7 @@ mdb_node_ptr_set_mdbPrev_np(mdb_node_t *node_ptr, word_t mdbPrev)
|
|||
static inline bool_t
|
||||
isValidVTableRoot_fp(cap_t vspace_root_cap)
|
||||
{
|
||||
#if defined(CONFIG_PAE_PAGING)
|
||||
return likely(cap_capType_equals(vspace_root_cap, cap_pdpt_cap) && cap_pdpt_cap_get_capPDPTIsMapped(vspace_root_cap));
|
||||
#else
|
||||
return likely(cap_capType_equals(vspace_root_cap, cap_page_directory_cap) && cap_page_directory_cap_get_capPDIsMapped(vspace_root_cap));
|
||||
#endif
|
||||
return cap_capType_equals(vspace_root_cap, cap_page_directory_cap) && cap_page_directory_cap_get_capPDIsMapped(vspace_root_cap);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
|
|
|||
|
|
@ -59,16 +59,6 @@ block page_directory_cap {
|
|||
field capType 4
|
||||
}
|
||||
|
||||
block pdpt_cap {
|
||||
padding 19
|
||||
field capPDPTIsMapped 1
|
||||
field capPDPTMappedASID 12
|
||||
|
||||
padding 1
|
||||
field_high capPDPTBasePtr 27
|
||||
field capType 4
|
||||
}
|
||||
|
||||
-- Cap to the table of 2^6 ASID pools
|
||||
block asid_control_cap {
|
||||
padding 32
|
||||
|
|
@ -201,7 +191,6 @@ tagged_union cap capType {
|
|||
tag frame_cap 1
|
||||
tag page_table_cap 3
|
||||
tag page_directory_cap 5
|
||||
tag pdpt_cap 7
|
||||
tag asid_control_cap 9
|
||||
tag asid_pool_cap 11
|
||||
tag io_space_cap 13
|
||||
|
|
@ -413,9 +402,6 @@ block pdpte {
|
|||
}
|
||||
|
||||
block pde_small {
|
||||
#ifdef CONFIG_PAE_PAGING
|
||||
padding 32
|
||||
#endif
|
||||
field_high pt_base_address 20
|
||||
field avl 3
|
||||
padding 1
|
||||
|
|
@ -430,9 +416,6 @@ block pde_small {
|
|||
}
|
||||
|
||||
block pde_large {
|
||||
#ifdef CONFIG_PAE_PAGING
|
||||
padding 32
|
||||
#endif
|
||||
field_high page_base_address 11
|
||||
padding 8
|
||||
field pat 1
|
||||
|
|
@ -454,9 +437,6 @@ tagged_union pde page_size {
|
|||
}
|
||||
|
||||
block pte {
|
||||
#ifdef CONFIG_PAE_PAGING
|
||||
padding 32
|
||||
#endif
|
||||
field_high page_base_address 20
|
||||
field avl 3
|
||||
field global 1
|
||||
|
|
|
|||
|
|
@ -23,16 +23,6 @@
|
|||
#define GDT_IPCBUF 7
|
||||
#define GDT_ENTRIES 8
|
||||
|
||||
#ifdef CONFIG_PAE_PAGING
|
||||
#define PDPTE_SIZE_BITS 3
|
||||
#define PDPT_INDEX_BITS 2
|
||||
#define PDE_SIZE_BITS 3
|
||||
#define PD_INDEX_BITS 9
|
||||
#define PTE_SIZE_BITS 3
|
||||
#define PT_INDEX_BITS 9
|
||||
#define X86_GLOBAL_VSPACE_ROOT ia32KSGlobalPDPT
|
||||
typedef pdpte_t vspace_root_t;
|
||||
#else
|
||||
#define PDPTE_SIZE_BITS 0
|
||||
#define PDPT_INDEX_BITS 0
|
||||
#define PDE_SIZE_BITS 2
|
||||
|
|
@ -41,7 +31,6 @@ typedef pdpte_t vspace_root_t;
|
|||
#define PT_INDEX_BITS 10
|
||||
#define X86_GLOBAL_VSPACE_ROOT ia32KSGlobalPD
|
||||
typedef pde_t vspace_root_t;
|
||||
#endif
|
||||
|
||||
#define GET_VSPACE_ROOT_INDEX(x) ((x) >> (seL4_PageBits + PT_INDEX_BITS))
|
||||
|
||||
|
|
@ -128,9 +117,6 @@ cap_get_capMappedASID(cap_t cap)
|
|||
ctag = cap_get_capType(cap);
|
||||
|
||||
switch (ctag) {
|
||||
case cap_pdpt_cap:
|
||||
return cap_pdpt_cap_get_capPDPTMappedASID(cap);
|
||||
|
||||
case cap_page_directory_cap:
|
||||
return cap_page_directory_cap_get_capPDMappedASID(cap);
|
||||
|
||||
|
|
|
|||
|
|
@ -168,9 +168,6 @@ cap_get_archCapSizeBits(cap_t cap)
|
|||
case cap_page_directory_cap:
|
||||
return seL4_PageDirBits;
|
||||
|
||||
case cap_pdpt_cap:
|
||||
return seL4_PDPTBits;
|
||||
|
||||
case cap_io_port_cap:
|
||||
return 0;
|
||||
case cap_io_space_cap:
|
||||
|
|
@ -221,9 +218,6 @@ cap_get_archCapIsPhysical(cap_t cap)
|
|||
case cap_page_directory_cap:
|
||||
return true;
|
||||
|
||||
case cap_pdpt_cap:
|
||||
return true;
|
||||
|
||||
case cap_io_port_cap:
|
||||
return false;
|
||||
|
||||
|
|
@ -276,9 +270,6 @@ cap_get_archCapPtr(cap_t cap)
|
|||
case cap_page_directory_cap:
|
||||
return PT_PTR(cap_page_directory_cap_get_capPDBasePtr(cap));
|
||||
|
||||
case cap_pdpt_cap:
|
||||
return PDPT_PTR(cap_pdpt_cap_get_capPDPTBasePtr(cap));
|
||||
|
||||
case cap_io_port_cap:
|
||||
return NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -18,11 +18,7 @@
|
|||
#define PADDR_LOAD 0x00100000
|
||||
#define PPTR_BASE 0xe0000000
|
||||
|
||||
#ifdef CONFIG_PAE_PAGING
|
||||
#define PPTR_USER_TOP (PPTR_BASE & (~MASK(seL4_HugePageBits)))
|
||||
#else
|
||||
#define PPTR_USER_TOP (PPTR_BASE & (~MASK(seL4_LargePageBits)))
|
||||
#endif
|
||||
|
||||
/* Calculate virtual address space reserved for TLB Bitmap. ROOT_ENTRIES
|
||||
* will be zero in the case where the bitmap is unused */
|
||||
|
|
|
|||
|
|
@ -14,12 +14,7 @@
|
|||
#include <autoconf.h>
|
||||
|
||||
#define SEL4_MAPPING_LOOKUP_LEVEL 2
|
||||
#ifdef CONFIG_PAE_PAGING
|
||||
#define SEL4_MAPPING_LOOKUP_NO_PT 21
|
||||
#define SEL4_MAPPING_LOOKUP_NO_PD 30
|
||||
#else
|
||||
#define SEL4_MAPPING_LOOKUP_NO_PT 22
|
||||
#endif
|
||||
|
||||
LIBSEL4_INLINE_FUNC seL4_Word seL4_MappingFailedLookupLevel(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -16,16 +16,9 @@
|
|||
#endif /* HAVE_AUTOCONF */
|
||||
|
||||
typedef enum _mode_object {
|
||||
#ifdef CONFIG_PAE_PAGING
|
||||
seL4_IA32_PDPTObject = seL4_NonArchObjectTypeCount,
|
||||
seL4_ModeObjectTypeCount
|
||||
#else
|
||||
seL4_ModeObjectTypeCount = seL4_NonArchObjectTypeCount,
|
||||
#endif
|
||||
} seL4_ModeObjectType;
|
||||
|
||||
#ifndef CONFIG_PAE_PAGING
|
||||
#define seL4_IA32_PDPTObject 0xffffffff
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -36,14 +36,6 @@ BEGIN_FUNC(enable_paging)
|
|||
orl $0x10, %eax
|
||||
movl %eax, %cr4
|
||||
|
||||
#ifdef CONFIG_PAE_PAGING
|
||||
# Set PAE (bit 5) so that we will switch to PAE paging mode
|
||||
# when we enable paging below
|
||||
movl %cr4, %eax
|
||||
orl $0x20, %eax
|
||||
movl %eax, %cr4
|
||||
#endif
|
||||
|
||||
# Load the boot PD (or PDPT) address into CR3
|
||||
leal _boot_pd, %eax
|
||||
movl %eax, %cr3
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
#
|
||||
|
||||
ARCH_C_SOURCES += 32/kernel/vspace_32paging.c \
|
||||
32/kernel/vspace_pae.c \
|
||||
32/kernel/thread.c \
|
||||
32/kernel/vspace.c \
|
||||
32/kernel/elf.c \
|
||||
|
|
|
|||
|
|
@ -220,18 +220,6 @@ map_kernel_window(
|
|||
pte_t pte;
|
||||
unsigned int UNUSED i;
|
||||
|
||||
if (config_set(CONFIG_PAE_PAGING)) {
|
||||
for (idx = 0; idx < BIT(PDPT_INDEX_BITS); idx++) {
|
||||
pdpte_ptr_new(&ia32KSGlobalPDPT[idx],
|
||||
pptr_to_paddr(&ia32KSGlobalPD[idx * BIT(PD_INDEX_BITS)]),
|
||||
0, /* avl*/
|
||||
0, /* cache_disabled */
|
||||
0, /* write_through */
|
||||
1 /* present */
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/* Mapping of PPTR_BASE (virtual address) to kernel's PADDR_BASE
|
||||
* up to end of virtual address space except for the last large page.
|
||||
*/
|
||||
|
|
@ -461,68 +449,18 @@ create_it_address_space(cap_t root_cnode_cap, v_region_t it_v_reg)
|
|||
seL4_SlotPos slot_pos_after;
|
||||
|
||||
slot_pos_before = ndks_boot.slot_pos_cur;
|
||||
if (PDPT_INDEX_BITS == 0) {
|
||||
cap_t pd_cap;
|
||||
pptr_t pd_pptr;
|
||||
/* just create single PD obj and cap */
|
||||
pd_pptr = alloc_region(seL4_PageDirBits);
|
||||
if (!pd_pptr) {
|
||||
return cap_null_cap_new();
|
||||
}
|
||||
memzero(PDE_PTR(pd_pptr), 1 << seL4_PageDirBits);
|
||||
copyGlobalMappings((vspace_root_t*)pd_pptr);
|
||||
pd_cap = create_it_page_directory_cap(cap_null_cap_new(), pd_pptr, 0, IT_ASID);
|
||||
write_slot(SLOT_PTR(pptr_of_cap(root_cnode_cap), seL4_CapInitThreadVSpace), pd_cap);
|
||||
vspace_cap = pd_cap;
|
||||
} else {
|
||||
cap_t pdpt_cap;
|
||||
pptr_t pdpt_pptr;
|
||||
unsigned int i;
|
||||
/* create a PDPT obj and cap */
|
||||
pdpt_pptr = alloc_region(seL4_PDPTBits);
|
||||
if (!pdpt_pptr) {
|
||||
return cap_null_cap_new();
|
||||
}
|
||||
memzero(PDPTE_PTR(pdpt_pptr), 1 << seL4_PDPTBits);
|
||||
pdpt_cap = cap_pdpt_cap_new(
|
||||
true, /* capPDPTISMapped */
|
||||
IT_ASID, /* capPDPTMappedASID */
|
||||
pdpt_pptr /* capPDPTBasePtr */
|
||||
);
|
||||
/* create all PD objs and caps necessary to cover userland image. For simplicity
|
||||
* to ensure we also cover the kernel window we create all PDs */
|
||||
for (i = 0; i < BIT(PDPT_INDEX_BITS); i++) {
|
||||
/* The compiler is under the mistaken belief here that this shift could be
|
||||
* undefined. However, in the case that it would be undefined this code path
|
||||
* is not reachable because PDPT_INDEX_BITS == 0 (see if statement at the top of
|
||||
* this function), so to work around it we must both put in a redundant
|
||||
* if statement AND place the shift in a variable. While the variable
|
||||
* will get compiled away it prevents the compiler from evaluating
|
||||
* the 1 << 32 as a constant when it shouldn't
|
||||
* tl;dr gcc evaluates constants even if code is unreachable */
|
||||
int shift = (PD_INDEX_BITS + PT_INDEX_BITS + PAGE_BITS);
|
||||
if (shift != 32) {
|
||||
vptr = i << shift;
|
||||
} else {
|
||||
return cap_null_cap_new();
|
||||
}
|
||||
|
||||
pptr = alloc_region(seL4_PageDirBits);
|
||||
if (!pptr) {
|
||||
return cap_null_cap_new();
|
||||
}
|
||||
memzero(PDE_PTR(pptr), 1 << seL4_PageDirBits);
|
||||
if (!provide_cap(root_cnode_cap,
|
||||
create_it_page_directory_cap(pdpt_cap, pptr, vptr, IT_ASID))
|
||||
) {
|
||||
return cap_null_cap_new();
|
||||
}
|
||||
}
|
||||
/* now that PDs exist we can copy the global mappings */
|
||||
copyGlobalMappings((vspace_root_t*)pdpt_pptr);
|
||||
write_slot(SLOT_PTR(pptr_of_cap(root_cnode_cap), seL4_CapInitThreadVSpace), pdpt_cap);
|
||||
vspace_cap = pdpt_cap;
|
||||
cap_t pd_cap;
|
||||
pptr_t pd_pptr;
|
||||
/* just create single PD obj and cap */
|
||||
pd_pptr = alloc_region(seL4_PageDirBits);
|
||||
if (!pd_pptr) {
|
||||
return cap_null_cap_new();
|
||||
}
|
||||
memzero(PDE_PTR(pd_pptr), 1 << seL4_PageDirBits);
|
||||
copyGlobalMappings((vspace_root_t*)pd_pptr);
|
||||
pd_cap = create_it_page_directory_cap(cap_null_cap_new(), pd_pptr, 0, IT_ASID);
|
||||
write_slot(SLOT_PTR(pptr_of_cap(root_cnode_cap), seL4_CapInitThreadVSpace), pd_cap);
|
||||
vspace_cap = pd_cap;
|
||||
|
||||
/* create all PT objs and caps necessary to cover userland image */
|
||||
|
||||
|
|
@ -698,11 +636,7 @@ void setVMRoot(tcb_t* tcb)
|
|||
vspace_root = getValidNativeRoot(threadRoot);
|
||||
if (!vspace_root) {
|
||||
SMP_COND_STATEMENT(tlb_bitmap_unset(paddr_to_pptr(getCurrentPD()), getCurrentCPUIndex());)
|
||||
if (config_set(CONFIG_PAE_PAGING)) {
|
||||
setCurrentPD(pptr_to_paddr(ia32KSGlobalPDPT));
|
||||
} else {
|
||||
setCurrentPD(pptr_to_paddr(ia32KSGlobalPD));
|
||||
}
|
||||
setCurrentPD(pptr_to_paddr(ia32KSGlobalPD));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -710,11 +644,7 @@ void setVMRoot(tcb_t* tcb)
|
|||
find_ret = findVSpaceForASID(asid);
|
||||
if (find_ret.status != EXCEPTION_NONE || find_ret.vspace_root != vspace_root) {
|
||||
SMP_COND_STATEMENT(tlb_bitmap_unset(paddr_to_pptr(getCurrentPD()), getCurrentCPUIndex());)
|
||||
if (config_set(CONFIG_PAE_PAGING)) {
|
||||
setCurrentPD(pptr_to_paddr(ia32KSGlobalPDPT));
|
||||
} else {
|
||||
setCurrentPD(pptr_to_paddr(ia32KSGlobalPD));
|
||||
}
|
||||
setCurrentPD(pptr_to_paddr(ia32KSGlobalPD));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -745,10 +675,6 @@ decodeX86ModeMMUInvocation(
|
|||
)
|
||||
{
|
||||
switch (cap_get_capType(cap)) {
|
||||
case cap_pdpt_cap:
|
||||
current_syscall_error.type = seL4_IllegalOperation;
|
||||
return EXCEPTION_SYSCALL_ERROR;
|
||||
|
||||
case cap_page_directory_cap:
|
||||
return decodeIA32PageDirectoryInvocation(invLabel, length, cte, cap, excaps, buffer);
|
||||
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@
|
|||
#include <arch/linker.h>
|
||||
#include <util.h>
|
||||
|
||||
#ifndef CONFIG_PAE_PAGING
|
||||
|
||||
/* setup initial boot page directory */
|
||||
|
||||
/* The boot pd is referenced by code that runs before paging, so
|
||||
|
|
@ -399,5 +397,3 @@ Arch_userStackTrace(tcb_t *tptr)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,479 +0,0 @@
|
|||
/*
|
||||
* Copyright 2014, General Dynamics C4 Systems
|
||||
*
|
||||
* This software may be distributed and modified according to the terms of
|
||||
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
|
||||
* See "LICENSE_GPLv2.txt" for details.
|
||||
*
|
||||
* @TAG(GD_GPL)
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <machine/io.h>
|
||||
#include <kernel/boot.h>
|
||||
#include <model/statedata.h>
|
||||
#include <arch/kernel/vspace.h>
|
||||
#include <util.h>
|
||||
|
||||
#ifdef CONFIG_PAE_PAGING
|
||||
|
||||
/* The boot pd is referenced by code that runs before paging, so
|
||||
* place it in PHYS_DATA. In PAE mode the top level is actually
|
||||
* a PDPTE, but we call it _boot_pd for compatibility */
|
||||
pdpte_t _boot_pd[BIT(PDPT_INDEX_BITS)] ALIGN(BIT(PAGE_BITS)) VISIBLE PHYS_BSS;
|
||||
/* Allocate enough page directories to fill every slot in the PDPT */
|
||||
pde_t _boot_pds[BIT(PD_INDEX_BITS + PDPT_INDEX_BITS)] ALIGN(BIT(PAGE_BITS)) VISIBLE PHYS_BSS;
|
||||
|
||||
BOOT_CODE
|
||||
pde_t *get_boot_pd()
|
||||
{
|
||||
/* return a pointer to the continus array of boot pds */
|
||||
return _boot_pds;
|
||||
}
|
||||
|
||||
/* These functions arefrom what is generated by the bitfield tool. It is
|
||||
* required by functions that need to call it before the MMU is turned on.
|
||||
* Any changes made to the bitfield generation need to be replicated here.
|
||||
*/
|
||||
PHYS_CODE
|
||||
static inline void
|
||||
pdpte_ptr_new_phys(pdpte_t *pdpte_ptr, uint32_t pd_base_address, uint32_t avl, uint32_t cache_disabled, uint32_t write_through, uint32_t present)
|
||||
{
|
||||
pdpte_ptr->words[0] = 0;
|
||||
pdpte_ptr->words[1] = 0;
|
||||
|
||||
pdpte_ptr->words[0] |= (pd_base_address & 0xfffff000) >> 0;
|
||||
pdpte_ptr->words[0] |= (avl & 0x7) << 9;
|
||||
pdpte_ptr->words[0] |= (cache_disabled & 0x1) << 4;
|
||||
pdpte_ptr->words[0] |= (write_through & 0x1) << 3;
|
||||
pdpte_ptr->words[0] |= (present & 0x1) << 0;
|
||||
}
|
||||
|
||||
PHYS_CODE
|
||||
static inline void
|
||||
pde_pde_large_ptr_new_phys(pde_t *pde_ptr, uint32_t page_base_address,
|
||||
uint32_t pat, uint32_t avl, uint32_t global, uint32_t dirty,
|
||||
uint32_t accessed, uint32_t cache_disabled, uint32_t write_through,
|
||||
uint32_t super_user, uint32_t read_write, uint32_t present)
|
||||
{
|
||||
pde_ptr->words[0] = 0;
|
||||
pde_ptr->words[1] = 0;
|
||||
|
||||
pde_ptr->words[0] |= (page_base_address & 0xffe00000) >> 0;
|
||||
pde_ptr->words[0] |= (pat & 0x1) << 12;
|
||||
pde_ptr->words[0] |= (avl & 0x7) << 9;
|
||||
pde_ptr->words[0] |= (global & 0x1) << 8;
|
||||
pde_ptr->words[0] |= ((uint32_t)pde_pde_large & 0x1) << 7;
|
||||
pde_ptr->words[0] |= (dirty & 0x1) << 6;
|
||||
pde_ptr->words[0] |= (accessed & 0x1) << 5;
|
||||
pde_ptr->words[0] |= (cache_disabled & 0x1) << 4;
|
||||
pde_ptr->words[0] |= (write_through & 0x1) << 3;
|
||||
pde_ptr->words[0] |= (super_user & 0x1) << 2;
|
||||
pde_ptr->words[0] |= (read_write & 0x1) << 1;
|
||||
pde_ptr->words[0] |= (present & 0x1) << 0;
|
||||
|
||||
}
|
||||
|
||||
PHYS_CODE VISIBLE void
|
||||
init_boot_pd(void)
|
||||
{
|
||||
word_t i;
|
||||
|
||||
/* first map in all the pds into the pdpt */
|
||||
for (i = 0; i < BIT(PDPT_INDEX_BITS); i++) {
|
||||
uint32_t pd_base = (uint32_t)&_boot_pds[i * BIT(PD_INDEX_BITS)];
|
||||
pdpte_ptr_new_phys(
|
||||
_boot_pd + i,
|
||||
pd_base, /* pd_base_address */
|
||||
0, /* avl */
|
||||
0, /* cache_disabled */
|
||||
0, /* write_through */
|
||||
1 /* present */
|
||||
);
|
||||
}
|
||||
|
||||
/* identity mapping from 0 up to PPTR_BASE (virtual address) */
|
||||
for (i = 0; (i << seL4_LargePageBits) < PPTR_BASE; i++) {
|
||||
pde_pde_large_ptr_new_phys(
|
||||
_boot_pds + i,
|
||||
i << seL4_LargePageBits, /* physical address */
|
||||
0, /* pat */
|
||||
0, /* avl */
|
||||
1, /* global */
|
||||
0, /* dirty */
|
||||
0, /* accessed */
|
||||
0, /* cache_disabled */
|
||||
0, /* write_through */
|
||||
0, /* super_user */
|
||||
1, /* read_write */
|
||||
1 /* present */
|
||||
);
|
||||
}
|
||||
|
||||
/* mapping of PPTR_BASE (virtual address) to PADDR_BASE up to end of virtual address space */
|
||||
for (i = 0; (i << seL4_LargePageBits) < -PPTR_BASE; i++) {
|
||||
pde_pde_large_ptr_new_phys(
|
||||
_boot_pds + i + (PPTR_BASE >> seL4_LargePageBits),
|
||||
(i << seL4_LargePageBits) + PADDR_BASE, /* physical address */
|
||||
0, /* pat */
|
||||
0, /* avl */
|
||||
1, /* global */
|
||||
0, /* dirty */
|
||||
0, /* accessed */
|
||||
0, /* cache_disabled */
|
||||
0, /* write_through */
|
||||
0, /* super_user */
|
||||
1, /* read_write */
|
||||
1 /* present */
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
BOOT_CODE void
|
||||
map_it_frame_cap(cap_t vspace_cap, cap_t frame_cap)
|
||||
{
|
||||
pdpte_t *pdpt = PDPTE_PTR(pptr_of_cap(vspace_cap));
|
||||
pde_t *pd;
|
||||
pte_t *pt;
|
||||
void *frame = (void*)cap_frame_cap_get_capFBasePtr(frame_cap);
|
||||
vptr_t vptr = cap_frame_cap_get_capFMappedAddress(frame_cap);
|
||||
|
||||
assert(cap_frame_cap_get_capFMappedASID(frame_cap) != 0);
|
||||
pdpt += (vptr >> seL4_HugePageBits);
|
||||
assert(pdpte_ptr_get_present(pdpt));
|
||||
pd = paddr_to_pptr(pdpte_ptr_get_pd_base_address(pdpt));
|
||||
pd += ( (vptr & MASK(seL4_HugePageBits)) >> seL4_LargePageBits);
|
||||
assert(pde_pde_small_ptr_get_present(pd));
|
||||
pt = paddr_to_pptr(pde_pde_small_ptr_get_pt_base_address(pd));
|
||||
pte_ptr_new(
|
||||
pt + ((vptr & MASK(seL4_LargePageBits)) >> seL4_PageBits),
|
||||
pptr_to_paddr(frame),
|
||||
0, /* avl */
|
||||
0, /* global */
|
||||
0, /* pat */
|
||||
0, /* dirty */
|
||||
0, /* accessed */
|
||||
0, /* cache_disabled */
|
||||
0, /* write_through */
|
||||
1, /* super_user */
|
||||
1, /* read_write */
|
||||
1 /* present */
|
||||
);
|
||||
invalidateLocalPageStructureCache();
|
||||
}
|
||||
|
||||
BOOT_CODE void
|
||||
map_it_pt_cap(cap_t vspace_cap, cap_t pt_cap)
|
||||
{
|
||||
pdpte_t *pdpt = PDPTE_PTR(pptr_of_cap(vspace_cap));
|
||||
pde_t *pd;
|
||||
pte_t *pt = PT_PTR(cap_page_table_cap_get_capPTBasePtr(pt_cap));
|
||||
vptr_t vptr = cap_page_table_cap_get_capPTMappedAddress(pt_cap);
|
||||
|
||||
assert(cap_page_table_cap_get_capPTIsMapped(pt_cap));
|
||||
pdpt += (vptr >> seL4_HugePageBits);
|
||||
assert(pdpte_ptr_get_present(pdpt));
|
||||
pd = paddr_to_pptr(pdpte_ptr_get_pd_base_address(pdpt));
|
||||
pde_pde_small_ptr_new(
|
||||
pd + (vptr >> seL4_LargePageBits),
|
||||
pptr_to_paddr(pt),
|
||||
0, /* avl*/
|
||||
0, /* accessed */
|
||||
0, /* cache_disabled */
|
||||
0, /* write_through */
|
||||
1, /* super_user */
|
||||
1, /* read_write */
|
||||
1 /* present */
|
||||
);
|
||||
invalidateLocalPageStructureCache();
|
||||
}
|
||||
|
||||
BOOT_CODE void
|
||||
map_it_pd_cap(cap_t vspace_cap, cap_t pd_cap)
|
||||
{
|
||||
pdpte_t *pdpt = PDPTE_PTR(pptr_of_cap(vspace_cap));
|
||||
pde_t *pd = PDE_PTR(cap_page_directory_cap_get_capPDBasePtr(pd_cap));
|
||||
vptr_t vptr = cap_page_directory_cap_get_capPDMappedAddress(pd_cap);
|
||||
|
||||
assert(cap_page_directory_cap_get_capPDIsMapped(pd_cap));
|
||||
pdpte_ptr_new(
|
||||
pdpt + (vptr >> seL4_HugePageBits),
|
||||
pptr_to_paddr(pd),
|
||||
0, /* avl */
|
||||
0, /* cache_disabled */
|
||||
0, /* write_through */
|
||||
1 /* present */
|
||||
);
|
||||
invalidateLocalPageStructureCache();
|
||||
}
|
||||
|
||||
/* ==================== BOOT CODE FINISHES HERE ==================== */
|
||||
|
||||
void copyGlobalMappings(vspace_root_t* new_vspace)
|
||||
{
|
||||
word_t i;
|
||||
pdpte_t *pdpt = (pdpte_t*)new_vspace;
|
||||
|
||||
for (i = PPTR_BASE >> seL4_HugePageBits; i < BIT(PDPT_INDEX_BITS); i++) {
|
||||
pdpt[i] = ia32KSGlobalPDPT[i];
|
||||
}
|
||||
}
|
||||
|
||||
bool_t CONST isVTableRoot(cap_t cap)
|
||||
{
|
||||
return cap_get_capType(cap) == cap_pdpt_cap;
|
||||
}
|
||||
|
||||
bool_t CONST isValidNativeRoot(cap_t cap)
|
||||
{
|
||||
if (!isVTableRoot(cap) ||
|
||||
!cap_pdpt_cap_get_capPDPTIsMapped(cap)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
vspace_root_t *getValidNativeRoot(cap_t vspace_cap)
|
||||
{
|
||||
if (isValidNativeRoot(vspace_cap)) {
|
||||
return PDPTE_PTR(cap_pdpt_cap_get_capPDPTBasePtr(vspace_cap));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline pdpte_t *lookupPDPTSlot(vspace_root_t *vspace, vptr_t vptr)
|
||||
{
|
||||
pdpte_t *pdpt = PDPT_PTR(vspace);
|
||||
return pdpt + (vptr >> seL4_HugePageBits);
|
||||
}
|
||||
|
||||
lookupPDSlot_ret_t lookupPDSlot(vspace_root_t *vspace, vptr_t vptr)
|
||||
{
|
||||
pdpte_t *pdptSlot;
|
||||
lookupPDSlot_ret_t ret;
|
||||
|
||||
pdptSlot = lookupPDPTSlot(vspace, vptr);
|
||||
|
||||
if (!pdpte_ptr_get_present(pdptSlot)) {
|
||||
current_lookup_fault = lookup_fault_missing_capability_new(PAGE_BITS + PT_INDEX_BITS + PD_INDEX_BITS);
|
||||
ret.pdSlot = NULL;
|
||||
ret.status = EXCEPTION_LOOKUP_FAULT;
|
||||
return ret;
|
||||
} else {
|
||||
pde_t *pd;
|
||||
pde_t *pdSlot;
|
||||
unsigned int pdIndex;
|
||||
|
||||
pd = paddr_to_pptr(pdpte_ptr_get_pd_base_address(pdptSlot));
|
||||
pdIndex = (vptr >> (PAGE_BITS + PT_INDEX_BITS)) & MASK(PD_INDEX_BITS);
|
||||
pdSlot = pd + pdIndex;
|
||||
|
||||
ret.pdSlot = pdSlot;
|
||||
ret.status = EXCEPTION_NONE;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
exception_t performASIDPoolInvocation(asid_t asid, asid_pool_t* poolPtr, cte_t* vspaceCapSlot)
|
||||
{
|
||||
cap_pdpt_cap_ptr_set_capPDPTMappedASID(&vspaceCapSlot->cap, asid);
|
||||
cap_pdpt_cap_ptr_set_capPDPTIsMapped(&vspaceCapSlot->cap, 1);
|
||||
poolPtr->array[asid & MASK(asidLowBits)] = PDPTE_PTR(cap_pdpt_cap_get_capPDPTBasePtr(vspaceCapSlot->cap));
|
||||
|
||||
return EXCEPTION_NONE;
|
||||
}
|
||||
|
||||
void unmapPageDirectory(asid_t asid, vptr_t vaddr, pde_t *pd)
|
||||
{
|
||||
findVSpaceForASID_ret_t find_ret;
|
||||
cap_t threadRoot;
|
||||
pdpte_t *pdptSlot;
|
||||
|
||||
find_ret = findVSpaceForASID(asid);
|
||||
if (find_ret.status != EXCEPTION_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
pdptSlot = lookupPDPTSlot(find_ret.vspace_root, vaddr);
|
||||
/* check if the PDPT has the PD */
|
||||
if (! (pdpte_ptr_get_present(pdptSlot) &&
|
||||
(pdpte_ptr_get_pd_base_address(pdptSlot) == pptr_to_paddr(pd)))) {
|
||||
return;
|
||||
}
|
||||
|
||||
*pdptSlot = pdpte_new(
|
||||
0, /* pd_base_address */
|
||||
0, /* avl */
|
||||
0, /* cache_disabled */
|
||||
0, /* write_through */
|
||||
0 /* present */
|
||||
);
|
||||
/* check if page directory belongs to current address space */
|
||||
threadRoot = TCB_PTR_CTE_PTR(NODE_STATE(ksCurThread), tcbVTable)->cap;
|
||||
if (isValidNativeRoot(threadRoot) && (vspace_root_t*)pptr_of_cap(threadRoot) == find_ret.vspace_root) {
|
||||
/* according to the intel manual if we modify a pdpt we must
|
||||
* reload cr3 */
|
||||
write_cr3(read_cr3());
|
||||
}
|
||||
invalidateLocalPageStructureCache();
|
||||
}
|
||||
|
||||
static exception_t
|
||||
performIA32PageDirectoryInvocationUnmap(cap_t cap, cte_t *ctSlot)
|
||||
{
|
||||
|
||||
if (cap_page_directory_cap_get_capPDIsMapped(cap)) {
|
||||
pde_t *pd = PDE_PTR(cap_page_directory_cap_get_capPDBasePtr(cap));
|
||||
unmapPageDirectory(
|
||||
cap_page_directory_cap_get_capPDMappedASID(cap),
|
||||
cap_page_directory_cap_get_capPDMappedAddress(cap),
|
||||
pd
|
||||
);
|
||||
clearMemory((void *)pd, cap_get_capSizeBits(cap));
|
||||
}
|
||||
cap_page_directory_cap_ptr_set_capPDIsMapped(&(ctSlot->cap), 0);
|
||||
|
||||
return EXCEPTION_NONE;
|
||||
}
|
||||
|
||||
static exception_t
|
||||
performIA32PageDirectoryInvocationMap(cap_t cap, cte_t *ctSlot, pdpte_t pdpte, pdpte_t *pdptSlot, cap_t threadRootCap, cap_t vspaceCap)
|
||||
{
|
||||
|
||||
ctSlot->cap = cap;
|
||||
*pdptSlot = pdpte;
|
||||
|
||||
|
||||
/* according to the intel manual if we modify a pdpt we must
|
||||
* reload cr3 */
|
||||
if (isValidNativeRoot(threadRootCap) && (vspace_root_t *)pptr_of_cap(threadRootCap) == (vspace_root_t *)pptr_of_cap(vspaceCap)) {
|
||||
write_cr3(read_cr3());
|
||||
}
|
||||
|
||||
invalidateLocalPageStructureCache();
|
||||
|
||||
return EXCEPTION_NONE;
|
||||
}
|
||||
|
||||
exception_t
|
||||
decodeIA32PageDirectoryInvocation(
|
||||
word_t invLabel,
|
||||
word_t length,
|
||||
cte_t* cte,
|
||||
cap_t cap,
|
||||
extra_caps_t excaps,
|
||||
word_t* buffer
|
||||
)
|
||||
{
|
||||
word_t vaddr;
|
||||
vm_attributes_t attr;
|
||||
pdpte_t* pdptSlot;
|
||||
cap_t vspaceCap;
|
||||
vspace_root_t* vspace;
|
||||
pdpte_t pdpte;
|
||||
paddr_t paddr;
|
||||
asid_t asid;
|
||||
cap_t threadRoot;
|
||||
|
||||
if (invLabel == X86PageDirectoryUnmap) {
|
||||
if (!isFinalCapability(cte)) {
|
||||
current_syscall_error.type = seL4_RevokeFirst;
|
||||
userError("X86PageDirectory: Cannot unmap if more than one cap exists.");
|
||||
return EXCEPTION_SYSCALL_ERROR;
|
||||
}
|
||||
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
||||
|
||||
return performIA32PageDirectoryInvocationUnmap(cap, cte);
|
||||
}
|
||||
|
||||
if (invLabel != X86PageDirectoryMap) {
|
||||
userError("X86PageDirectory: Illegal operation.");
|
||||
current_syscall_error.type = seL4_IllegalOperation;
|
||||
return EXCEPTION_SYSCALL_ERROR;
|
||||
}
|
||||
|
||||
if (length < 2 || excaps.excaprefs[0] == NULL) {
|
||||
userError("X86PageDirectory: Truncated message.");
|
||||
current_syscall_error.type = seL4_TruncatedMessage;
|
||||
return EXCEPTION_SYSCALL_ERROR;
|
||||
}
|
||||
|
||||
if (cap_page_directory_cap_get_capPDIsMapped(cap)) {
|
||||
userError("X86PageDirectory: Page directory is already mapped to a PDPT.");
|
||||
current_syscall_error.type = seL4_InvalidCapability;
|
||||
current_syscall_error.invalidCapNumber = 0;
|
||||
return EXCEPTION_SYSCALL_ERROR;
|
||||
}
|
||||
|
||||
vaddr = getSyscallArg(0, buffer) & (~MASK(seL4_HugePageBits));
|
||||
attr = vmAttributesFromWord(getSyscallArg(1, buffer));
|
||||
vspaceCap = excaps.excaprefs[0]->cap;
|
||||
|
||||
if (!isValidNativeRoot(vspaceCap)) {
|
||||
current_syscall_error.type = seL4_InvalidCapability;
|
||||
current_syscall_error.invalidCapNumber = 1;
|
||||
return EXCEPTION_SYSCALL_ERROR;
|
||||
}
|
||||
|
||||
vspace = (vspace_root_t*)pptr_of_cap(vspaceCap);
|
||||
asid = cap_get_capMappedASID(vspaceCap);
|
||||
|
||||
if (vaddr >= PPTR_USER_TOP) {
|
||||
userError("X86PageDirectory: Mapping address too high.");
|
||||
current_syscall_error.type = seL4_InvalidArgument;
|
||||
current_syscall_error.invalidArgumentNumber = 0;
|
||||
return EXCEPTION_SYSCALL_ERROR;
|
||||
}
|
||||
|
||||
{
|
||||
findVSpaceForASID_ret_t find_ret;
|
||||
|
||||
find_ret = findVSpaceForASID(asid);
|
||||
if (find_ret.status != EXCEPTION_NONE) {
|
||||
current_syscall_error.type = seL4_FailedLookup;
|
||||
current_syscall_error.failedLookupWasSource = false;
|
||||
return EXCEPTION_SYSCALL_ERROR;
|
||||
}
|
||||
|
||||
if (find_ret.vspace_root != vspace) {
|
||||
current_syscall_error.type = seL4_InvalidCapability;
|
||||
current_syscall_error.invalidCapNumber = 1;
|
||||
return EXCEPTION_SYSCALL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
pdptSlot = lookupPDPTSlot(vspace, vaddr);
|
||||
|
||||
if (pdpte_ptr_get_present(pdptSlot)) {
|
||||
current_syscall_error.type = seL4_DeleteFirst;
|
||||
return EXCEPTION_SYSCALL_ERROR;
|
||||
}
|
||||
|
||||
paddr = pptr_to_paddr(PDE_PTR(cap_page_directory_cap_get_capPDBasePtr(cap)));
|
||||
pdpte = pdpte_new(
|
||||
paddr, /* pd_base_address */
|
||||
0, /* avl */
|
||||
vm_attributes_get_x86PCDBit(attr), /* cache_disabled */
|
||||
vm_attributes_get_x86PWTBit(attr), /* write_through */
|
||||
1 /* present */
|
||||
);
|
||||
|
||||
cap = cap_page_directory_cap_set_capPDIsMapped(cap, 1);
|
||||
cap = cap_page_directory_cap_set_capPDMappedASID(cap, asid);
|
||||
cap = cap_page_directory_cap_set_capPDMappedAddress(cap, vaddr);
|
||||
|
||||
threadRoot = TCB_PTR_CTE_PTR(NODE_STATE(ksCurThread), tcbVTable)->cap;
|
||||
|
||||
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
||||
return performIA32PageDirectoryInvocationMap(cap, cte, pdpte, pdptSlot, threadRoot, vspaceCap);
|
||||
}
|
||||
|
||||
#if CONFIG_PRINTING
|
||||
/* FIXME implement */
|
||||
void
|
||||
Arch_userStackTrace(tcb_t *tptr)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -60,15 +60,6 @@ cap_t Mode_finaliseCap(cap_t cap, bool_t final)
|
|||
{
|
||||
switch (cap_get_capType(cap)) {
|
||||
|
||||
case cap_pdpt_cap:
|
||||
if (final && cap_pdpt_cap_get_capPDPTIsMapped(cap)) {
|
||||
deleteASID(
|
||||
cap_pdpt_cap_get_capPDPTMappedASID(cap),
|
||||
(vspace_root_t*)PDPTE_PTR(cap_pdpt_cap_get_capPDPTBasePtr(cap))
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case cap_frame_cap:
|
||||
if (final && cap_frame_cap_get_capFMappedASID(cap)) {
|
||||
switch (cap_frame_cap_get_capFMapType(cap)) {
|
||||
|
|
@ -177,9 +168,7 @@ Mode_createObject(object_t t, void *regionBase, word_t userSize, bool_t deviceMe
|
|||
);
|
||||
|
||||
case seL4_X86_PageDirectoryObject:
|
||||
#ifndef CONFIG_PAE_PAGING
|
||||
copyGlobalMappings(regionBase);
|
||||
#endif
|
||||
return cap_page_directory_cap_new(
|
||||
0, /* capPDIsMapped */
|
||||
asidInvalid, /* capPDMappedASID */
|
||||
|
|
@ -187,17 +176,6 @@ Mode_createObject(object_t t, void *regionBase, word_t userSize, bool_t deviceMe
|
|||
(word_t)regionBase /* capPDBasePtr */
|
||||
);
|
||||
|
||||
#ifdef CONFIG_PAE_PAGING
|
||||
case seL4_IA32_PDPTObject:
|
||||
copyGlobalMappings(regionBase);
|
||||
|
||||
return cap_pdpt_cap_new(
|
||||
0, /* capPDPTIsMapped */
|
||||
asidInvalid, /* capPDPTMappedAsid*/
|
||||
(word_t)regionBase /* capPDPTBasePtr */
|
||||
);
|
||||
#endif
|
||||
|
||||
case seL4_X86_IOPageTableObject:
|
||||
return cap_io_page_table_cap_new(
|
||||
0, /* capIOPTIsMapped */
|
||||
|
|
@ -224,7 +202,6 @@ Mode_decodeInvocation(
|
|||
)
|
||||
{
|
||||
switch (cap_get_capType(cap)) {
|
||||
case cap_pdpt_cap:
|
||||
case cap_page_directory_cap:
|
||||
case cap_page_table_cap:
|
||||
case cap_frame_cap:
|
||||
|
|
|
|||
|
|
@ -53,18 +53,6 @@ deriveCap_ret_t Arch_deriveCap(cte_t* slot, cap_t cap)
|
|||
}
|
||||
return ret;
|
||||
|
||||
case cap_pdpt_cap:
|
||||
if (cap_pdpt_cap_get_capPDPTIsMapped(cap)) {
|
||||
ret.cap = cap;
|
||||
ret.status = EXCEPTION_NONE;
|
||||
} else {
|
||||
userError("Deriving a PDPT cap without an assigned ASID");
|
||||
current_syscall_error.type = seL4_IllegalOperation;
|
||||
ret.cap = cap_null_cap_new();
|
||||
ret.status = EXCEPTION_SYSCALL_ERROR;
|
||||
}
|
||||
return ret;
|
||||
|
||||
case cap_asid_control_cap:
|
||||
case cap_asid_pool_cap:
|
||||
ret.cap = cap;
|
||||
|
|
@ -332,13 +320,6 @@ bool_t CONST Arch_sameRegionAs(cap_t cap_a, cap_t cap_b)
|
|||
}
|
||||
break;
|
||||
|
||||
case cap_pdpt_cap:
|
||||
if (cap_get_capType(cap_b) == cap_pdpt_cap) {
|
||||
return cap_pdpt_cap_get_capPDPTBasePtr(cap_a) ==
|
||||
cap_pdpt_cap_get_capPDPTBasePtr(cap_b);
|
||||
}
|
||||
break;
|
||||
|
||||
case cap_asid_control_cap:
|
||||
if (cap_get_capType(cap_b) == cap_asid_control_cap) {
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -89,14 +89,6 @@ config MAX_VPIDS
|
|||
should be sized as small as possible to save memory, but be at least
|
||||
the number of VCPUs that will be run for optimum performance
|
||||
|
||||
config PAE_PAGING
|
||||
bool "Use PAE Paging"
|
||||
depends on ARCH_IA32
|
||||
default n
|
||||
help
|
||||
PAE paging uses 4K/2M pages and has three levels of paging. If this
|
||||
is not used the old 32-bit paging with 4K/4M pages will be used
|
||||
|
||||
config HUGE_PAGE
|
||||
bool "Use 1GB Huge Page"
|
||||
depends on ARCH_X86_64
|
||||
|
|
|
|||
Loading…
Reference in a new issue