diff --git a/arch/x86/include/asm/page.h b/arch/x86/include/asm/page.h index f182e017..ec86e800 100644 --- a/arch/x86/include/asm/page.h +++ b/arch/x86/include/asm/page.h @@ -31,49 +31,62 @@ #include #include -#define _PAGE_BIT_PRESENT 0 /* is present */ -#define _PAGE_BIT_RW 1 /* writeable */ -#define _PAGE_BIT_USER 2 /* userspace addressable */ -#define _PAGE_BIT_PWT 3 /* page write through */ -#define _PAGE_BIT_PCD 4 /* page cache disabled */ -#define _PAGE_BIT_ACCESSED 5 /* was accessed (raised by CPU) */ -#define _PAGE_BIT_DIRTY 6 /* was written to (raised by CPU) */ -#define _PAGE_BIT_PSE 7 /* 4 MB (or 2MB) page */ -#define _PAGE_BIT_PAT 7 /* on 4KB pages */ -#define _PAGE_BIT_GLOBAL 8 /* Global TLB entry PPro+ */ -#define _PAGE_BIT_SVM_STRONG 9 /* mark a virtual address range as used by the SVM system */ -#define _PAGE_BIT_SVM_LAZYRELEASE 10 /* mark a virtual address range as used by the SVM system */ -#define _PAGE_BIT_SVM_INIT 11 /* mark if the MBP proxy is used */ +// 4KB pages +#define PAGE_SHIFT 12 + +#ifdef CONFIG_X86_32 + #define PAGE_MAP_LEVELS 2 + #define PAGE_MAP_SHIFT 10 +#elif defined(CONFIG_X86_64) + #define PAGE_MAP_LEVELS 4 + #define PAGE_MAP_SHIFT 9 +#endif + +// base addresses of page map structures +#ifdef CONFIG_X86_32 + #define PAGE_PGD 0xFFFFF000 + #define PAGE_PGT 0xFFC00000 +#elif defined(CONFIG_X86_64) + #define PAGE_PML4 0xFFFFFFFFFFFFF000 + #define PAGE_PDPT 0xFFFFFFFFFFE00000 + #define PAGE_PGD 0xFFFFFFFFC0000000 + #define PAGE_PGT 0xFFFFFF8000000000 +#endif + +#define PAGE_MAP_ENTRIES (1 << PAGE_MAP_SHIFT) +#define PAGE_SIZE (1 << PAGE_SHIFT) +#define PAGE_MASK ~(PAGE_SIZE - 1) +#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK) /// Page is present -#define PG_PRESENT (1 << _PAGE_BIT_PRESENT) +#define PG_PRESENT (1 << 0) /// Page is read- and writable -#define PG_RW (1 << _PAGE_BIT_RW) +#define PG_RW (1 << 1) /// Page is addressable from userspace -#define PG_USER (1 << _PAGE_BIT_USER) +#define PG_USER (1 << 2) /// Page write through is activated -#define PG_PWT (1 << _PAGE_BIT_PWT) +#define PG_PWT (1 << 3) /// Page cache is disabled -#define PG_PCD (1 << _PAGE_BIT_PCD) +#define PG_PCD (1 << 4) /// Page was recently accessed (set by CPU) -#define PG_ACCESSED (1 << _PAGE_BIT_ACCESSED) +#define PG_ACCESSED (1 << 5) /// Page is dirty due to recentwrite-access (set by CPU) -#define PG_DIRTY (1 << _PAGE_BIT_DIRTY) +#define PG_DIRTY (1 << 6) /// Big page: 4MB (or 2MB) -#define PG_PSE (1 << _PAGE_BIT_PSE) +#define PG_PSE (1 << 7) /// Page is part of the MPB (SCC specific entry) #define PG_MPE PG_PSE /// Global TLB entry (Pentium Pro and later) -#define PG_GLOBAL (1 << _PAGE_BIT_GLOBAL) +#define PG_GLOBAL (1 << 8) /// Pattern flag -#define PG_PAT (1 << _PAGE_BIT_PAT) +#define PG_PAT (1 << 7) /// This virtual address range is used by SVM system as marked -#define PG_SVM PG_SVM_STRONG -#define PG_SVM_STRONG (1 << _PAGE_BIT_SVM_STRONG) +#define PG_SVM (1 << 9) +#define PG_SVM_STRONG PG_SVM_STRONG /// This virtual address range is used by SVM system as marked -#define PG_SVM_LAZYRELEASE (1 << _PAGE_BIT_SVM_LAZYRELEASE) +#define PG_SVM_LAZYRELEASE (1 << 10) /// Currently, no page frame is behind this page (only the MBP proxy) -#define PG_SVM_INIT (1 << _PAGE_BIT_SVM_INIT) +#define PG_SVM_INIT (1 << 11) /// This is a whole set of flags (PRESENT,RW,ACCESSED,DIRTY) for kernelspace tables #define KERN_TABLE (PG_PRESENT|PG_RW|PG_ACCESSED|PG_DIRTY) @@ -84,21 +97,13 @@ /// This is a whole set of flags (PRESENT,RW,USER) for userspace pages #define USER_PAGE (PG_PRESENT|PG_RW|PG_USER) -#ifdef CONFIG_X86_32 -/// On a 32-bit system, each page map structure consists of 1024 entries (= 2^10) -#define MAP_ENTRIES 1024 -#elif defined(CONFIG_X86_64) -/// On a 64-bit system, each page map structure consists of 512 entries (= 2^9) -#define MAP_ENTRIES 512 -#endif - /** @brief General page map structure * * This page map structure is a general type for all indirecton levels.\n * As all page map levels containing the same amount of entries. */ typedef struct page_map { - size_t entries[MAP_ENTRIES]; + size_t entries[PAGE_MAP_ENTRIES]; } __attribute__ ((aligned (4096))) page_map_t; /** @brief Converts a virtual address to a physical diff --git a/arch/x86/kernel/entry64.asm b/arch/x86/kernel/entry64.asm index 27925901..eaf5ccba 100644 --- a/arch/x86/kernel/entry64.asm +++ b/arch/x86/kernel/entry64.asm @@ -88,11 +88,11 @@ SECTION .data ; create default page tables for the 64bit kernel global boot_pml4 ALIGN 4096 ; of course, the page tables have to be page aligned -MAP_ENTRIES equ 512 -boot_pml4 times MAP_ENTRIES DQ 0 -boot_pdpt times MAP_ENTRIES DQ 0 -boot_pd times MAP_ENTRIES DQ 0 -boot_pt times (MAP_ENTRIES*MAP_ENTRIES) DQ 0 ; 1GB kernel space +PAGE_MAP_ENTRIES equ 512 +boot_pml4 times PAGE_MAP_ENTRIES DQ 0 +boot_pdpt times PAGE_MAP_ENTRIES DQ 0 +boot_pd times PAGE_MAP_ENTRIES DQ 0 +boot_pt times (PAGE_MAP_ENTRIES*PAGE_MAP_ENTRIES) DQ 0 ; 1GB kernel space SECTION .text ALIGN 8 @@ -317,7 +317,7 @@ init_paging: mov DWORD [edi], boot_pdpt or DWORD [edi], 0x3 - add edi, MAP_ENTRIES-1 ; create self reference for recursive paging + add edi, (PAGE_MAP_ENTRIES-1)*8 ; setup recursive paging mov DWORD [edi], boot_pml4 ; boot_pml4[511] -> boot_pml4 or DWORD [edi], 0x3 ; set present and writable flags @@ -327,7 +327,7 @@ init_paging: mov edi, boot_pd mov ebx, boot_pt - mov ecx, MAP_ENTRIES + mov ecx, PAGE_MAP_ENTRIES .l1: mov DWORD [edi], ebx or DWORD [edi], 0x3 ; set present and writable flags diff --git a/arch/x86/mm/page64.c b/arch/x86/mm/page64.c index 1e16bc49..7b28fad1 100644 --- a/arch/x86/mm/page64.c +++ b/arch/x86/mm/page64.c @@ -355,22 +355,22 @@ size_t vm_alloc(uint32_t npages, uint32_t flags) // => physical address of the page table is identical of the virtual address pdpt = (page_map_t*) (task->page_map->entries[index_pml4] & PAGE_MASK); if (!pdpt) { - i += (size_t)MAP_ENTRIES*MAP_ENTRIES*MAP_ENTRIES*PAGE_SIZE; - j += MAP_ENTRIES*MAP_ENTRIES*MAP_ENTRIES; + i += (size_t)PAGE_MAP_ENTRIES*PAGE_MAP_ENTRIES*PAGE_MAP_ENTRIES*PAGE_SIZE; + j += PAGE_MAP_ENTRIES*PAGE_MAP_ENTRIES*PAGE_MAP_ENTRIES; continue; } pgd = (page_map_t*) (pdpt->entries[index_pdpt] & PAGE_MASK); if (!pgd) { - i += MAP_ENTRIES*MAP_ENTRIES*PAGE_SIZE; - j += MAP_ENTRIES*MAP_ENTRIES; + i += PAGE_MAP_ENTRIES*PAGE_MAP_ENTRIES*PAGE_SIZE; + j += PAGE_MAP_ENTRIES*PAGE_MAP_ENTRIES; continue; } pgt = (page_map_t*) (pgd->entries[index_pgd] & PAGE_MASK); if (!pgt) { - i += MAP_ENTRIES*PAGE_SIZE; - j += MAP_ENTRIES; + i += PAGE_MAP_ENTRIES*PAGE_SIZE; + j += PAGE_MAP_ENTRIES; continue; } @@ -424,22 +424,22 @@ int unmap_region(size_t viraddr, uint32_t npages) // => physical address of the page table is identical of the virtual address pdpt = (page_map_t*) (task->page_map->entries[index_pml4] & PAGE_MASK); if (!pdpt) { - viraddr += (size_t) MAP_ENTRIES*MAP_ENTRIES*MAP_ENTRIES*PAGE_SIZE; - i += MAP_ENTRIES*MAP_ENTRIES*MAP_ENTRIES; + viraddr += (size_t) PAGE_MAP_ENTRIES*PAGE_MAP_ENTRIES*PAGE_MAP_ENTRIES*PAGE_SIZE; + i += PAGE_MAP_ENTRIES*PAGE_MAP_ENTRIES*PAGE_MAP_ENTRIES; continue; } pgd = (page_map_t*) (pdpt->entries[index_pdpt] & PAGE_MASK); if (!pgd) { - viraddr += MAP_ENTRIES*MAP_ENTRIES*PAGE_SIZE; - i += MAP_ENTRIES*MAP_ENTRIES; + viraddr += PAGE_MAP_ENTRIES*PAGE_MAP_ENTRIES*PAGE_SIZE; + i += PAGE_MAP_ENTRIES*PAGE_MAP_ENTRIES; continue; } pgt = (page_map_t*) (pgd->entries[index_pgd] & PAGE_MASK); if (!pgt) { - viraddr += MAP_ENTRIES*PAGE_SIZE; - i += MAP_ENTRIES; + viraddr += PAGE_MAP_ENTRIES*PAGE_SIZE; + i += PAGE_MAP_ENTRIES; continue; } @@ -491,22 +491,22 @@ int vm_free(size_t viraddr, uint32_t npages) // => physical address of the page table is identical of the virtual address pdpt = (page_map_t*) (task->page_map->entries[index_pml4] & PAGE_MASK); if (!pdpt) { - viraddr += (size_t) MAP_ENTRIES*MAP_ENTRIES*MAP_ENTRIES*PAGE_SIZE; - i += MAP_ENTRIES*MAP_ENTRIES*MAP_ENTRIES; + viraddr += (size_t) PAGE_MAP_ENTRIES*PAGE_MAP_ENTRIES*PAGE_MAP_ENTRIES*PAGE_SIZE; + i += PAGE_MAP_ENTRIES*PAGE_MAP_ENTRIES*PAGE_MAP_ENTRIES; continue; } pgd = (page_map_t*) (pdpt->entries[index_pdpt] & PAGE_MASK); if (!pgd) { - viraddr += MAP_ENTRIES*MAP_ENTRIES*PAGE_SIZE; - i += MAP_ENTRIES*MAP_ENTRIES; + viraddr += PAGE_MAP_ENTRIES*PAGE_MAP_ENTRIES*PAGE_SIZE; + i += PAGE_MAP_ENTRIES*PAGE_MAP_ENTRIES; continue; } pgt = (page_map_t*) (pgd->entries[index_pgd] & PAGE_MASK); if (!pgt) { - viraddr += MAP_ENTRIES*PAGE_SIZE; - i += MAP_ENTRIES; + viraddr += PAGE_MAP_ENTRIES*PAGE_SIZE; + i += PAGE_MAP_ENTRIES; continue; } diff --git a/include/metalsvm/stddef.h b/include/metalsvm/stddef.h index 131286a6..725365e2 100644 --- a/include/metalsvm/stddef.h +++ b/include/metalsvm/stddef.h @@ -32,10 +32,6 @@ extern "C" { typedef unsigned int tid_t; -#define PAGE_SIZE (1 << PAGE_SHIFT) -#define PAGE_MASK ~(PAGE_SIZE - 1) -#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK) - #if MAX_CORES == 1 #define per_core(name) name #define DECLARE_PER_CORE(type, name) extern type name; diff --git a/kernel/main.c b/kernel/main.c index 723d7092..59355390 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #ifdef CONFIG_ROCKCREEK #include