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
|
/// The number of entries in a page map table
|
||||||
#define PAGE_MAP_ENTRIES (1L << PAGE_MAP_BITS)
|
#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
|
/// Align to next page
|
||||||
#define PAGE_FLOOR(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK)
|
#define PAGE_FLOOR(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK)
|
||||||
/// Align to page
|
/// Align to page
|
||||||
#define PAGE_CEIL(addr) ( (addr) & PAGE_MASK)
|
#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
|
/// Page is present
|
||||||
#define PG_PRESENT (1 << 0)
|
#define PG_PRESENT (1 << 0)
|
||||||
/// Page is read- and writable
|
/// Page is read- and writable
|
||||||
|
|
|
@ -37,36 +37,38 @@
|
||||||
*/
|
*/
|
||||||
static inline size_t sign_extend(ssize_t addr, int bits)
|
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)
|
static inline page_entry_t* get_child_entry(page_entry_t *entry)
|
||||||
{
|
{
|
||||||
size_t child = (size_t) entry;
|
size_t child = (size_t) entry;
|
||||||
|
|
||||||
child <<= PAGE_MAP_BITS;
|
child <<= PAGE_MAP_BITS;
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
return (page_entry_t*) CANONICAL(child);
|
||||||
return (page_entry_t*) child;
|
|
||||||
#elif defined(CONFIG_X86_64)
|
|
||||||
return (page_entry_t*) sign_extend(child, VIRT_BITS);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @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)
|
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_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*) CANONICAL(parent);
|
||||||
return (page_entry_t*) (parent & ~0x3);
|
|
||||||
#elif defined(CONFIG_X86_64)
|
|
||||||
return (page_entry_t*) sign_extend(parent & ~0x7, VIRT_BITS);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Get the corresponding page map entry to a given virtual address
|
/** @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
|
* Please note: this implementation requires that the tables are mapped
|
||||||
* at the end of VAS!
|
* 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_BITS;
|
||||||
addr |= (PAGE_MAP_ENTRIES-1) << (PAGE_MAP_LEVELS * PAGE_MAP_BITS + 3); // TODO
|
addr |= PAGE_MAP_PGT;
|
||||||
} while (level--);
|
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
addr >>= level * PAGE_MAP_BITS;
|
||||||
return (page_entry_t*) (addr & ~0x3);
|
addr &= ~(sizeof(size_t) - 1); // align to page_entry_t
|
||||||
#elif defined(CONFIG_X86_64)
|
|
||||||
return (page_entry_t*) sign_extend(addr & ~0x7, VIRT_BITS);
|
return (page_entry_t*) CANONICAL(addr);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Get the corresponding virtual address to a page map entry */
|
/** @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;
|
addr <<= (level+1) * PAGE_MAP_BITS;
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
return CANONICAL(addr);
|
||||||
return addr;
|
|
||||||
#elif defined(CONFIG_X86_64)
|
|
||||||
return sign_extend(addr, VIRT_BITS); // sign extend
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Converts a virtual address to a physical
|
/** @brief Converts a virtual address to a physical
|
||||||
|
@ -150,6 +145,7 @@ size_t get_page_flags(size_t viraddr)
|
||||||
int i;
|
int i;
|
||||||
for (i=1; i<PAGE_MAP_LEVELS; i++) {
|
for (i=1; i<PAGE_MAP_LEVELS; i++) {
|
||||||
entry = virt_to_entry(viraddr, i);
|
entry = virt_to_entry(viraddr, i);
|
||||||
|
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_64
|
||||||
flags |= (*entry & PG_XD);
|
flags |= (*entry & PG_XD);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -59,9 +59,9 @@ extern page_entry_t boot_pml4[PAGE_MAP_ENTRIES];
|
||||||
static spinlock_t kslock = SPINLOCK_INIT;
|
static spinlock_t kslock = SPINLOCK_INIT;
|
||||||
|
|
||||||
/// Mapping of self referenced page map (at the end of the VAS)
|
/// 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 current_map = (page_entry_t*) (1 * PAGE_MAP_PML4);
|
||||||
static page_entry_t* const src_map = (page_entry_t*) (-2*PAGE_SIZE);
|
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_SIZE);
|
static page_entry_t* const dest_map = (page_entry_t*) (3 * PAGE_MAP_PML4);
|
||||||
|
|
||||||
page_entry_t* get_boot_page_map(void)
|
page_entry_t* get_boot_page_map(void)
|
||||||
{
|
{
|
||||||
|
@ -159,10 +159,12 @@ void page_stats(int reset)
|
||||||
if (*entry & (1 << i))
|
if (*entry & (1 << i))
|
||||||
stats[i]++;
|
stats[i]++;
|
||||||
}
|
}
|
||||||
|
#ifdef CONFIG_X86_64
|
||||||
for (i=0; i<1; i++) { // IA-32e / PAE bits
|
for (i=0; i<1; i++) { // IA-32e / PAE bits
|
||||||
if (*entry & (1 << (63-i)))
|
if (*entry & (1 << (63-i)))
|
||||||
stats[i+PAGE_BITS]++;
|
stats[i+PAGE_BITS]++;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (reset) { // reset accessed and dirty bits
|
if (reset) { // reset accessed and dirty bits
|
||||||
*entry &= ~(PG_ACCESSED|PG_DIRTY);
|
*entry &= ~(PG_ACCESSED|PG_DIRTY);
|
||||||
|
|
Loading…
Add table
Reference in a new issue