You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
103 lines
4.1 KiB
C
103 lines
4.1 KiB
C
/* Copyright (C) 2021,2022 fef <owo@fef.moe>. All rights reserved. */
|
|
|
|
#pragma once
|
|
#ifndef _ARCH_PAGE_H_
|
|
#error "This file is not meant to be included directly, use <arch/page.h>"
|
|
#endif
|
|
|
|
/** @brief Binary logarithm of `HUGEPAGE_SIZE`. */
|
|
#define HUGEPAGE_SHIFT 22
|
|
|
|
#ifndef _ASM_SOURCE
|
|
|
|
#include <gay/cdefs.h>
|
|
#include <gay/types.h>
|
|
|
|
/**
|
|
* @brief A single 32-bit Page Table Entry.
|
|
* The layout matches that of the Intel SDM, vol 3, sect 4.3, fig 4-4.
|
|
* Bits 9 and 10 (`slab` and `atomic`) are marked as AVL in the manual and
|
|
* ignored by the MMU. We only use them for `get_pflags()`/`set_pflags()`.
|
|
*/
|
|
struct x86_page_table_entry {
|
|
/* 0 */bool present:1; /**< Page Fault on access if 0 */
|
|
/* 1 */bool rw:1; /**< Page Fault on write if 0 */
|
|
/* 2 */bool user:1; /**< Page Fault on user mode access if 0 */
|
|
/* 3 */bool write_through:1; /**< Enable write-through caching */
|
|
/* 4 */bool cache_disabled:1; /**< Disable caching in TLB */
|
|
/* 5 */bool accessed:1; /**< 1 if page has been accessed */
|
|
/* 6 */bool dirty:1; /**< 1 if page has been written to */
|
|
/* 7 */unsigned _reserved0:1;
|
|
/* 8 */bool global:1; /**< Don't update the TLB on table swap if 1 */
|
|
/* 9 */bool slab:1; /**< Used by the slab allocator */
|
|
/* 10 */bool atomic:1; /**< Allocated atomically */
|
|
/* 11 */unsigned _unused:1;
|
|
/* 12 */uintptr_t shifted_address:20; /**< Aligned pointer to the physical page */
|
|
} __packed;
|
|
#define __PFLAG_PRESENT (1 << 0)
|
|
#define __PFLAG_RW (1 << 1)
|
|
#define __PFLAG_USER (1 << 2)
|
|
#define __PFLAG_WRITE_THROUGH (1 << 3)
|
|
#define __PFLAG_NOCACHE (1 << 4)
|
|
#define __PFLAG_ACCESSED (1 << 5)
|
|
#define __PFLAG_DIRTY (1 << 6)
|
|
#define __PFLAG_GLOBAL (1 << 8)
|
|
#define __PFLAG_SLAB (1 << 9)
|
|
#define __PFLAG_ATOMIC (1 << 10)
|
|
|
|
struct x86_page_table {
|
|
struct x86_page_table_entry entries[1024];
|
|
} __aligned(PAGE_SIZE);
|
|
|
|
/**
|
|
* @brief Currently active page table at position `index` in the page directory.
|
|
* The last entry in the page directory is mapped to itself, therefore being
|
|
* interpreted by the MMU as a page table. This has the effect that the last
|
|
* page table, i.e. the page directory again, maps the entire page directory
|
|
* structure so it can be manipulated while paging is active. See the comment
|
|
* at the beginning of `arch/x86/mm/page.c` for a more detailed explanation.
|
|
*
|
|
* @param index Table index in the page directory
|
|
*/
|
|
#define X86_CURRENT_PT(index) ( &((struct x86_page_table *)X86_PD_OFFSET)[index] )
|
|
#define X86_CURRENT_PTE(pd_index, pt_index) (&(X86_CURRENT_PT(pd_index)->entries[pt_index]))
|
|
|
|
struct x86_page_directory_entry {
|
|
/* 0 */bool present:1; /**< Page Fault on access if 0 */
|
|
/* 1 */bool rw:1; /**< Page Fault on write if 0 */
|
|
/* 2 */bool user:1; /**< Page Fault on user mode access if 0 */
|
|
/* 3 */bool write_through:1; /**< Enable write-through caching */
|
|
/* 4 */bool cache_disabled:1; /**< Disable caching in TLB */
|
|
/* 5 */bool accessed:1; /**< 1 if page has been accessed */
|
|
/* 6 */unsigned _reserved0:1;
|
|
/* 7 */bool huge:1; /**< 0 = 4K, 1 = 4M */
|
|
/* 8 */unsigned _reserved1:1;
|
|
/* 9 */bool slab:1; /**< Used by the slab allocator (only if `!huge`) */
|
|
/* 10 */bool atomic:1; /**< Allocated atomically (only if `!huge`) */
|
|
/* 11 */unsigned _unused:1;
|
|
/* 12 */uintptr_t shifted_address:20; /**< Aligned pointer to `struct x86_page_table` */
|
|
} __packed;
|
|
#define __PFLAG_HUGE (1 << 7)
|
|
|
|
struct x86_page_directory {
|
|
struct x86_page_directory_entry entries[1024];
|
|
} __aligned(PAGE_SIZE);
|
|
|
|
/**
|
|
* @brief Currently active page directory.
|
|
* The last entry in the page directory is mapped to itself, therefore being
|
|
* interpreted by the MMU as a page table. See the comment at the start of
|
|
* `arch/x86/mm/page.c` for a more detailed explanation.
|
|
*/
|
|
#define X86_CURRENT_PD ((struct x86_page_directory *)X86_CURRENT_PT(1023))
|
|
#define X86_CURRENT_PDE(index) (&X86_CURRENT_PD->entries[index])
|
|
|
|
/**
|
|
* @brief Arch dependent virtual memory information data structure (x86 version).
|
|
* Outside of `/arch/x86`, this is treated as a completely obfuscated type,
|
|
* and only pointers to it are stored and passed around.
|
|
*/
|
|
typedef struct x86_page_directory vm_info_t;
|
|
|
|
#endif /* not _ASM_SOURCE */
|