diff --git a/include/arch/x86/page.h b/include/arch/x86/page.h index 552fc16a..7ab2c177 100644 --- a/include/arch/x86/page.h +++ b/include/arch/x86/page.h @@ -117,6 +117,7 @@ #define PADDR_MASK (~(PADDR_SIZE - 1)) #define VIRT_KERNEL_BASE _U64(0xffffffff80000000) +#define VIRT_KERNEL_HIGH _U64(0xffff900000000000) #define VIRT_USER_BASE _U64(0x0000000000400000) #define VIRT_IDENT_BASE _U64(0x0000000000000000) @@ -150,12 +151,19 @@ static inline paddr_t mfn_to_paddr(mfn_t mfn) { return (paddr_t)(mfn << PAGE_SHI static inline void *_paddr_to_virt(paddr_t pa, unsigned long addr_space) { return _ptr(pa + addr_space); } + static inline void *paddr_to_virt_kern(paddr_t pa) { return _paddr_to_virt(pa, VIRT_KERNEL_BASE); } + +static inline void *paddr_to_virt_high(paddr_t pa) { + return _paddr_to_virt(pa, VIRT_KERNEL_HIGH); +} + static inline void *paddr_to_virt_user(paddr_t pa) { return _paddr_to_virt(pa, VIRT_USER_BASE); } + static inline void *paddr_to_virt(paddr_t pa) { return _paddr_to_virt(pa, VIRT_IDENT_BASE); } @@ -163,9 +171,15 @@ static inline void *paddr_to_virt(paddr_t pa) { static inline void *mfn_to_virt_kern(mfn_t mfn) { return paddr_to_virt_kern(mfn << PAGE_SHIFT); } + +static inline void *mfn_to_virt_high(mfn_t mfn) { + return paddr_to_virt_high(mfn << PAGE_SHIFT); +} + static inline void *mfn_to_virt_user(mfn_t mfn) { return paddr_to_virt_user(mfn << PAGE_SHIFT); } + static inline void *mfn_to_virt(mfn_t mfn) { return paddr_to_virt(mfn << PAGE_SHIFT); } static inline paddr_t virt_to_paddr(const void *va) { @@ -173,6 +187,8 @@ static inline paddr_t virt_to_paddr(const void *va) { if (IS_ADDR_SPACE_VA(va, VIRT_KERNEL_BASE)) return pa - VIRT_KERNEL_BASE; + if (IS_ADDR_SPACE_VA(va, VIRT_KERNEL_HIGH)) + return pa - VIRT_KERNEL_HIGH; if (IS_ADDR_SPACE_VA(va, VIRT_USER_BASE)) return pa - VIRT_USER_BASE; @@ -196,6 +212,19 @@ static inline void *kmap(mfn_t mfn, unsigned int order, l3_flags, l2_flags, l1_flags); } +static inline void *mmap(mfn_t mfn, unsigned int order, +#if defined(__x86_64__) + unsigned long l4_flags, +#endif + unsigned long l3_flags, unsigned long l2_flags, + unsigned long l1_flags) { + return vmap(mfn_to_virt_high(mfn), mfn, order, +#if defined(__x86_64__) + l4_flags, +#endif + l3_flags, l2_flags, l1_flags); +} + static inline void *vmap_1g(void *va, mfn_t mfn, unsigned long l3_flags) { return vmap(va, mfn, PAGE_ORDER_1G, L4_PROT_USER, l3_flags, PT_NO_FLAGS, PT_NO_FLAGS); } @@ -222,6 +251,18 @@ static inline void *kmap_4k(mfn_t mfn, unsigned long l1_flags) { return kmap(mfn, PAGE_ORDER_4K, L4_PROT_USER, L3_PROT_USER, L2_PROT_USER, l1_flags); } +static inline void *mmap_1g(mfn_t mfn, unsigned long l3_flags) { + return mmap(mfn, PAGE_ORDER_1G, L4_PROT_USER, l3_flags, PT_NO_FLAGS, PT_NO_FLAGS); +} + +static inline void *mmap_2m(mfn_t mfn, unsigned long l2_flags) { + return mmap(mfn, PAGE_ORDER_2M, L4_PROT_USER, L3_PROT_USER, l2_flags, PT_NO_FLAGS); +} + +static inline void *mmap_4k(mfn_t mfn, unsigned long l1_flags) { + return mmap(mfn, PAGE_ORDER_4K, L4_PROT_USER, L3_PROT_USER, L2_PROT_USER, l1_flags); +} + #endif /* __ASSEMBLY__ */ #endif /* KTF_PAGE_H */ diff --git a/include/mm/vmm.h b/include/mm/vmm.h index b0fd5e81..60e5a733 100644 --- a/include/mm/vmm.h +++ b/include/mm/vmm.h @@ -31,6 +31,7 @@ enum gfp_flags { GFP_KERNEL = 0x00000001, GFP_USER = 0x00000002, GFP_IDENT = 0x00000004, + GFP_KERNEL_HIGH = 0x00000008, }; /* External definitions */ diff --git a/mm/vmm.c b/mm/vmm.c index 8a86acf8..4759a670 100644 --- a/mm/vmm.c +++ b/mm/vmm.c @@ -50,6 +50,8 @@ void *get_free_pages(unsigned int order, uint32_t flags) { L2_PROT_USER, L1_PROT_USER); if (flags & GFP_KERNEL) va = kmap(mfn, order, L4_PROT, L3_PROT, L2_PROT, L1_PROT); + if (flags & GFP_KERNEL_HIGH) + va = mmap(mfn, order, L4_PROT, L3_PROT, L2_PROT, L1_PROT); return va; }