205 lines
7.9 KiB
C
205 lines
7.9 KiB
C
/**
|
|
* \file
|
|
* \brief ARMv8 kernel page-table structures.
|
|
*/
|
|
|
|
/*
|
|
* Copyright (c) 2015, ETH Zurich.
|
|
* All rights reserved.
|
|
*
|
|
* This file is distributed under the terms in the attached LICENSE file.
|
|
* If you do not find this file, copies can be found by writing to:
|
|
* ETH Zurich D-INFK, Universitaetstr 6, CH-8092 Zurich. Attn: Systems Group.
|
|
*/
|
|
|
|
#ifndef KERNEL_ARCH_ARMv8_PAGING_H
|
|
#define KERNEL_ARCH_ARMv8_PAGING_H
|
|
|
|
// XXX: Not sure if these includes are required
|
|
#include <capabilities.h>
|
|
#include <barrelfish_kpi/cpu.h>
|
|
#include <barrelfish_kpi/paging_arch.h>
|
|
#include <sysreg.h>
|
|
|
|
|
|
// Resolves to the required number of entries in Ln to map `limit' number of bytes.
|
|
#define ARMv8_L0_ENTRIES(limit) (VMSAv8_64_L0_INDEX((limit) - 1) + 1)
|
|
#define ARMv8_L1_ENTRIES(limit) (VMSAv8_64_L1_INDEX((limit) - 1) + 1)
|
|
#define ARMv8_L2_ENTRIES(limit) (VMSAv8_64_L2_INDEX((limit) - 1) + 1)
|
|
#define ARMv8_L3_ENTRIES(limit) (VMSAv8_64_L3_INDEX((limit) - 1) + 1)
|
|
|
|
/**
|
|
* A translation table entry for VMSAv8-64 stage 1.
|
|
*/
|
|
union armv8_ttable_entry {
|
|
uint64_t raw;
|
|
struct {
|
|
uint64_t valid :1;
|
|
uint64_t mb1 :1; // 1 -> table, 0 -> block
|
|
uint64_t ignored1 :10; // lower block attrs, ignored for table
|
|
uint64_t base :36; // base address of next level table
|
|
uint64_t reserved1 :4;
|
|
uint64_t ignored2 :7;
|
|
uint64_t pxntable :1; // only stage 1, executable from EL1
|
|
uint64_t uxntable :1; // only stage 1, executable from EL0
|
|
uint64_t aptable :2; // only stage 1, access from EL0
|
|
uint64_t nstable :1; // only stage 1, access from secure state
|
|
} d;
|
|
struct {
|
|
uint64_t valid :1;
|
|
uint64_t mb0 :1; // 1 -> table, 0 -> block
|
|
uint64_t attrindex :3; // mem attr index field, D4-1798
|
|
uint64_t ns :1; // non-secure bit
|
|
uint64_t ap :2; // access permissions bits
|
|
uint64_t sh :2; // shareability field
|
|
uint64_t af :1; // accessed flag
|
|
uint64_t ng :1; // not global bit
|
|
uint64_t reserved1 :18;
|
|
uint64_t base :18;
|
|
uint64_t reserved2 :4;
|
|
uint64_t contiguous :1; // hint that entry is part of set
|
|
// of contiguous entries, D4-1811
|
|
uint64_t pxn :1; // privileged execute never bit
|
|
uint64_t uxn :1; // (user) execute never bit
|
|
uint64_t avail1 :4; // available for SW use
|
|
uint64_t ignored1 :5;
|
|
} block_l1;
|
|
struct {
|
|
uint64_t valid :1;
|
|
uint64_t mb0 :1; // 1 -> table, 0 -> block
|
|
uint64_t attrindex :3; // mem attr index field, D4-1798
|
|
uint64_t ns :1; // non-secure bit
|
|
uint64_t ap :2; // access permissions bits
|
|
uint64_t sh :2; // shareability field
|
|
uint64_t af :1; // accessed flag
|
|
uint64_t ng :1; // not global bit
|
|
uint64_t reserved1 :9;
|
|
uint64_t base :27;
|
|
uint64_t reserved2 :4;
|
|
uint64_t contiguous :1; // hint that entry is part of set
|
|
// of contiguous entries, D4-1811
|
|
uint64_t pxn :1; // privileged execute never bit
|
|
uint64_t uxn :1; // (user) execute never bit
|
|
uint64_t avail1 :4; // available for SW use
|
|
uint64_t ignored1 :5;
|
|
} block_l2;
|
|
struct {
|
|
uint64_t valid :1;
|
|
uint64_t mb1 :1; // 0 -> makes entry invalid
|
|
uint64_t attrindex :3; // mem attr index field, D4-1798
|
|
uint64_t ns :1; // non-secure bit
|
|
uint64_t ap :2; // access permissions bits
|
|
uint64_t sh :2; // shareability field
|
|
uint64_t af :1; // accessed flag
|
|
uint64_t ng :1; // not global bit
|
|
uint64_t base :36;
|
|
uint64_t reserved1 :4;
|
|
uint64_t contiguous :1; // hint that entry is part of set
|
|
// of contiguous entries, D4-1811
|
|
uint64_t pxn :1; // privileged execute never bit
|
|
uint64_t uxn :1; // (user) execute never bit
|
|
uint64_t avail1 :4; // available for SW use
|
|
uint64_t ignored1 :5;
|
|
} page;
|
|
};
|
|
|
|
STATIC_ASSERT_SIZEOF(union armv8_ttable_entry, sizeof(uint64_t));
|
|
|
|
|
|
|
|
/**
|
|
* Setup bootstrap page table with direct and relocated mappings for kernel.
|
|
*
|
|
* This function does not enable paging.
|
|
*
|
|
* @param initial_base
|
|
* @param initial_size
|
|
*/
|
|
void paging_map_kernel(uintptr_t initial_base, size_t initial_size);
|
|
|
|
lvaddr_t paging_map_device(lpaddr_t base, size_t size);
|
|
|
|
/**
|
|
* \brief Return whether we have enabled the MMU. Useful for
|
|
* initialization assertions
|
|
*/
|
|
extern bool paging_mmu_enabled(void);
|
|
|
|
/**
|
|
* Maps a device to a l2 page.
|
|
* Assumption: corresponding L1 entry already set
|
|
*
|
|
*/
|
|
|
|
void paging_map_device_page(uintptr_t l1_table,
|
|
lvaddr_t device_vbase,
|
|
lpaddr_t device_pbase,
|
|
size_t device_bytes);
|
|
|
|
/**
|
|
* Add kernel mappings to newly constructed page table.
|
|
*
|
|
* @param new_table_addr address of newly constructed page table.
|
|
* @param new_table_bytes size of newly constructed page table.
|
|
*/
|
|
void paging_make_good(lpaddr_t base);
|
|
|
|
void paging_map_table_l0(union armv8_ttable_entry *table_addr, lvaddr_t vaddr, lpaddr_t paddr);
|
|
|
|
void paging_map_table_l1(union armv8_ttable_entry *table_addr, lvaddr_t vaddr, lpaddr_t paddr);
|
|
|
|
void paging_map_table_l2(union armv8_ttable_entry *table_addr, lvaddr_t vaddr, lpaddr_t paddr);
|
|
|
|
void paging_map_block_l1(union armv8_ttable_entry *table_addr, lvaddr_t vaddr, lpaddr_t paddr, uintptr_t flags);
|
|
|
|
void paging_map_block_l2(union armv8_ttable_entry *table_addr, lvaddr_t vaddr, lpaddr_t paddr, uintptr_t flags);
|
|
|
|
void paging_map_page_l3(union armv8_ttable_entry *table_addr, lvaddr_t vaddr, lpaddr_t paddr, uintptr_t flags);
|
|
|
|
void paging_set_l3_entry(union armv8_ttable_entry *l3_entry, lpaddr_t pa, uintptr_t flags);
|
|
|
|
//void paging_set_l2_entry(union armv8_ttable_entry *l2entry, lpaddr_t paddr, uintptr_t flags);
|
|
//
|
|
//void paging_set_l3_entry(union armv8_ttable_entry *l2entry, lpaddr_t paddr, uintptr_t flags);
|
|
//
|
|
void paging_context_switch(lpaddr_t table_addr);
|
|
|
|
void paging_arm_reset(lpaddr_t paddr, size_t bytes);
|
|
|
|
|
|
// REVIEW: [2010-05-04 orion]
|
|
// these were deprecated in churn, enabling now to get system running again.
|
|
|
|
void paging_map_kernel_section(union armv8_ttable_entry *ttbase,lvaddr_t vbase, lpaddr_t pbase);
|
|
void paging_map_kernel_l1_block(union armv8_ttable_entry *ttbase,lvaddr_t vbase, lpaddr_t pbase);
|
|
|
|
void paging_map_memory(union armv8_ttable_entry *ttbase, lpaddr_t paddr, size_t bytes);
|
|
|
|
static inline bool is_root_pt(enum objtype type) {
|
|
return type == ObjType_VNode_AARCH64_l0;
|
|
}
|
|
|
|
static inline size_t get_pte_size(void) {
|
|
return PTABLE_ENTRY_SIZE;
|
|
}
|
|
|
|
static inline void do_one_tlb_flush(genvaddr_t vaddr)
|
|
{
|
|
// TODO: figure out selective flushing for ARMv8
|
|
sysreg_invalidate_tlb();
|
|
}
|
|
|
|
static inline void do_selective_tlb_flush(genvaddr_t vaddr, genvaddr_t vend)
|
|
{
|
|
// TODO: figure out selective flushing for ARMv8
|
|
sysreg_invalidate_tlb();
|
|
}
|
|
|
|
static inline void do_full_tlb_flush(void)
|
|
{
|
|
sysreg_invalidate_tlb();
|
|
}
|
|
|
|
|
|
#endif // KERNEL_ARCH_ARMv8_PAGING_H
|