simplified macros
This commit is contained in:
parent
c1e52dc8c2
commit
1f641e440c
3 changed files with 49 additions and 33 deletions
|
@ -68,11 +68,29 @@
|
|||
/// The number of entries in a page map table
|
||||
#define PAGE_MAP_ENTRIES (1L << PAGE_MAP_BITS)
|
||||
|
||||
// Base addresses of the self-mapped pagetables
|
||||
#ifdef CONFIG_X86_32
|
||||
#define PAGE_MAP_PGD 0xFFFFF000
|
||||
#define PAGE_MAP_PGT 0xFFC00000
|
||||
#elif defined(CONFIG_X86_64)
|
||||
#define PAGE_MAP_PML4 0xFFFFFFFFFFFFF000
|
||||
#define PAGE_MAP_PDPT 0xFFFFFFFFFFE00000
|
||||
#define PAGE_MAP_PGD 0xFFFFFFFFC0000000
|
||||
#define PAGE_MAP_PGT 0xFFFFFF8000000000
|
||||
#endif
|
||||
|
||||
/// Align to next page
|
||||
#define PAGE_FLOOR(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK)
|
||||
/// Align to page
|
||||
#define PAGE_CEIL(addr) ( (addr) & PAGE_MASK)
|
||||
|
||||
// Canonical address format
|
||||
#ifdef CONFIG_x86_32
|
||||
#define CANONICAL(addr) (addr)
|
||||
#elif defined(CONFIG_X86_64)
|
||||
#define CANONICAL(addr) sign_extend(addr, VIRT_BITS)
|
||||
#endif
|
||||
|
||||
/// Page is present
|
||||
#define PG_PRESENT (1 << 0)
|
||||
/// Page is read- and writable
|
||||
|
|
|
@ -37,36 +37,38 @@
|
|||
*/
|
||||
static inline size_t sign_extend(ssize_t addr, int bits)
|
||||
{
|
||||
return (addr << -bits) >> -bits; // sign bit is maintained during arithmetic right shift
|
||||
int shift = BITS - bits;
|
||||
return (addr << shift) >> shift; // sign bit gets copied during arithmetic right shift
|
||||
}
|
||||
|
||||
/** @brief */
|
||||
/** @brief Get the base address of the child table
|
||||
*
|
||||
* @param entry The parent entry
|
||||
* @return The child entry
|
||||
*/
|
||||
static inline page_entry_t* get_child_entry(page_entry_t *entry)
|
||||
{
|
||||
size_t child = (size_t) entry;
|
||||
|
||||
child <<= PAGE_MAP_BITS;
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
return (page_entry_t*) child;
|
||||
#elif defined(CONFIG_X86_64)
|
||||
return (page_entry_t*) sign_extend(child, VIRT_BITS);
|
||||
#endif
|
||||
return (page_entry_t*) CANONICAL(child);
|
||||
}
|
||||
|
||||
/** @brief */
|
||||
/** @brief Get the base address of the parent entry
|
||||
*
|
||||
* @param entry The child entry
|
||||
* @return The parent entry
|
||||
*/
|
||||
static inline page_entry_t* get_parent_entry(page_entry_t *entry)
|
||||
{
|
||||
size_t parent = (size_t) entry;
|
||||
ssize_t parent = (size_t) entry;
|
||||
|
||||
parent >>= PAGE_MAP_BITS;
|
||||
parent |= (PAGE_MAP_ENTRIES-1) << (PAGE_MAP_LEVELS * PAGE_MAP_BITS + 3); // TODO
|
||||
parent |= PAGE_MAP_PGT;
|
||||
parent &= ~(sizeof(size_t) - 1); // align to page_entry_t
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
return (page_entry_t*) (parent & ~0x3);
|
||||
#elif defined(CONFIG_X86_64)
|
||||
return (page_entry_t*) sign_extend(parent & ~0x7, VIRT_BITS);
|
||||
#endif
|
||||
return (page_entry_t*) CANONICAL(parent);
|
||||
}
|
||||
|
||||
/** @brief Get the corresponding page map entry to a given virtual address
|
||||
|
@ -74,18 +76,15 @@ static inline page_entry_t* get_parent_entry(page_entry_t *entry)
|
|||
* Please note: this implementation requires that the tables are mapped
|
||||
* at the end of VAS!
|
||||
*/
|
||||
static inline page_entry_t* virt_to_entry(size_t addr, int level)
|
||||
static inline page_entry_t* virt_to_entry(ssize_t addr, int level)
|
||||
{
|
||||
do {
|
||||
addr >>= PAGE_MAP_BITS;
|
||||
addr |= (PAGE_MAP_ENTRIES-1) << (PAGE_MAP_LEVELS * PAGE_MAP_BITS + 3); // TODO
|
||||
} while (level--);
|
||||
addr >>= PAGE_MAP_BITS;
|
||||
addr |= PAGE_MAP_PGT;
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
return (page_entry_t*) (addr & ~0x3);
|
||||
#elif defined(CONFIG_X86_64)
|
||||
return (page_entry_t*) sign_extend(addr & ~0x7, VIRT_BITS);
|
||||
#endif
|
||||
addr >>= level * PAGE_MAP_BITS;
|
||||
addr &= ~(sizeof(size_t) - 1); // align to page_entry_t
|
||||
|
||||
return (page_entry_t*) CANONICAL(addr);
|
||||
}
|
||||
|
||||
/** @brief Get the corresponding virtual address to a page map entry */
|
||||
|
@ -95,11 +94,7 @@ static inline size_t entry_to_virt(page_entry_t* entry, int level)
|
|||
|
||||
addr <<= (level+1) * PAGE_MAP_BITS;
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
return addr;
|
||||
#elif defined(CONFIG_X86_64)
|
||||
return sign_extend(addr, VIRT_BITS); // sign extend
|
||||
#endif
|
||||
return CANONICAL(addr);
|
||||
}
|
||||
|
||||
/** @brief Converts a virtual address to a physical
|
||||
|
@ -150,6 +145,7 @@ size_t get_page_flags(size_t viraddr)
|
|||
int i;
|
||||
for (i=1; i<PAGE_MAP_LEVELS; i++) {
|
||||
entry = virt_to_entry(viraddr, i);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
flags |= (*entry & PG_XD);
|
||||
#endif
|
||||
|
|
|
@ -59,9 +59,9 @@ extern page_entry_t boot_pml4[PAGE_MAP_ENTRIES];
|
|||
static spinlock_t kslock = SPINLOCK_INIT;
|
||||
|
||||
/// Mapping of self referenced page map (at the end of the VAS)
|
||||
static page_entry_t* const current_map = (page_entry_t*) (-1*PAGE_SIZE);
|
||||
static page_entry_t* const src_map = (page_entry_t*) (-2*PAGE_SIZE);
|
||||
static page_entry_t* const dest_map = (page_entry_t*) (-3*PAGE_SIZE);
|
||||
static page_entry_t* const current_map = (page_entry_t*) (1 * PAGE_MAP_PML4);
|
||||
static page_entry_t* const src_map = (page_entry_t*) (2 * PAGE_MAP_PML4);
|
||||
static page_entry_t* const dest_map = (page_entry_t*) (3 * PAGE_MAP_PML4);
|
||||
|
||||
page_entry_t* get_boot_page_map(void)
|
||||
{
|
||||
|
@ -159,10 +159,12 @@ void page_stats(int reset)
|
|||
if (*entry & (1 << i))
|
||||
stats[i]++;
|
||||
}
|
||||
#ifdef CONFIG_X86_64
|
||||
for (i=0; i<1; i++) { // IA-32e / PAE bits
|
||||
if (*entry & (1 << (63-i)))
|
||||
stats[i+PAGE_BITS]++;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (reset) { // reset accessed and dirty bits
|
||||
*entry &= ~(PG_ACCESSED|PG_DIRTY);
|
||||
|
|
Loading…
Add table
Reference in a new issue