Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "paging.h"
- #include "asm.h"
- #include "pfa.h"
- #include "bootscreen_output.h"
- #define SET(field) field |= 0b1
- #define CLEAR(field) field &= 0b0
- typedef struct {
- uint8_t present : 1;
- uint8_t read_write : 1;
- uint8_t user_supervisor : 1;
- uint8_t cache_policy : 1;
- uint8_t cache_disable : 1;
- uint8_t accessed : 1;
- uint8_t reserved : 3; // Must be 0b000
- uint8_t avl_3 : 3;
- uint64_t pdp_addr : 40;
- uint16_t avl_11 : 11;
- uint8_t no_execute : 1;
- } PML4entry;
- typedef struct {
- uint8_t present : 1;
- uint8_t read_write : 1;
- uint8_t user_supervisor : 1;
- uint8_t cache_policy : 1;
- uint8_t cache_disable : 1;
- uint8_t accessed : 1;
- uint8_t mbz : 3; // Must be 0 to also ensure it corresponds to 4kb paging
- uint8_t avl_3 : 3;
- uint64_t pd_addr : 40;
- uint16_t avl_11 : 11;
- uint8_t no_execute : 1;
- } PDPentry;
- typedef struct {
- uint8_t present : 1;
- uint8_t read_write : 1;
- uint8_t user_supervisor : 1;
- uint8_t cache_policy : 1;
- uint8_t cache_disable : 1;
- uint8_t accessed : 1;
- uint8_t mbz : 3; // Must be 0 to also ensure it corresponds to 4kb paging
- uint8_t avl_3 : 3;
- uint64_t pt_addr : 40;
- uint16_t avl_11 : 11;
- uint8_t no_execute : 1;
- } PDentry;
- typedef struct {
- uint8_t present : 1;
- uint8_t read_write : 1;
- uint8_t user_supervisor : 1;
- uint8_t cache_policy : 1;
- uint8_t cache_disable : 1;
- uint8_t accessed : 1;
- uint8_t dirty : 1;
- uint8_t pat : 1;
- uint8_t global : 1;
- uint8_t avl_3 : 3;
- uint64_t page_base_addr : 40;
- uint16_t avl_11 : 11;
- uint8_t no_execute : 1;
- } PTentry;
- /* Must all be aligned on 0b1000000000000 (4096) byte boundaries*/
- static __declspec(align(4096)) PML4entry PML4tab[512] = { 0 }; /* Fill page tables empty; ensures reserved bits are all cleared */
- static __declspec(align(4096)) PDPentry PDPtab[512] = { 0 };
- static __declspec(align(4096)) PDentry PDtab[512] = { 0 };
- static __declspec(align(4096)) PTentry PTtab[512] = { 0 };
- static void* make_canonical(void* addr) {
- size_t naddr = (size_t)addr;
- if (naddr & ((size_t)1 << 47))
- naddr |= 0xFFFF000000000000;
- return (void*)naddr;
- }
- static void* decanonical(void* addr) {
- return (void*)((size_t)addr & 0x0000FFFFFFFFFFFF);
- }
- void paging_init() {
- printLn("Hello");
- write_cr3((void*)PML4tab);
- printLn("Written pml4 table to cr3");
- }
- void paging_map(void* vaddr, size_t len, size_t attrset)
- {
- while (len)
- {
- uint16_t pml4offset = ((size_t)decanonical(vaddr) >> 39) & 0x1FF;
- uint16_t pdpoffset = ((size_t)decanonical(vaddr) >> 30) & 0x1FF;
- uint16_t pdoffset = ((size_t)decanonical(vaddr) >> 21) & 0x1FF;
- uint16_t ptoffset = ((size_t)decanonical(vaddr) >> 12) & 0x1FF;
- uint16_t ppoffset = (size_t)decanonical(vaddr) & 0x1FF;
- PML4entry pml4entry = PML4tab[pml4offset];
- PDPentry pdpentry = PDPtab[pdpoffset];
- PDentry pdentry = PDtab[pdoffset];
- PTentry ptentry = PTtab[ptoffset];
- if (!(ptentry.present & 0x1)) {
- /* Page is present, now we have to swap to the pagefile. */
- }
- else {
- //Page is not present, make a new page.
- ptentry.page_base_addr = (pfa_alloc() >> 12);
- }
- pdentry.pt_addr = ((uint64_t)PTtab >> 12);
- pdpentry.pd_addr = ((uint64_t)PDtab >> 12);
- pml4entry.pdp_addr = ((uint64_t)PDPtab >> 12);
- ptentry.present, pdentry.present, pdpentry.present, pml4entry.present = 0b1; // Set the present bit
- if (attrset >> 1) //Read/write => read/write set
- {
- SET(ptentry.read_write);
- SET(pdentry.read_write);
- SET(pdpentry.read_write);
- SET(pml4entry.read_write);
- }
- else // read only set
- {
- CLEAR(ptentry.read_write);
- CLEAR(pdentry.read_write);
- CLEAR(pdpentry.read_write);
- CLEAR(pml4entry.read_write);
- }
- if (attrset >> 2) // User/Supervisor => user and supervisor set
- {
- SET(ptentry.user_supervisor);
- SET(pdentry.user_supervisor);
- SET(pdpentry.user_supervisor);
- SET(pml4entry.user_supervisor);
- }
- else // User only set
- {
- CLEAR(ptentry.user_supervisor);
- CLEAR(pdentry.user_supervisor);
- CLEAR(pdpentry.user_supervisor);
- CLEAR(pml4entry.user_supervisor);
- }
- if (attrset >> 3) // Writethrough/writeback => writethrough set
- {
- SET(ptentry.cache_policy);
- SET(pdentry.cache_policy);
- SET(pdpentry.cache_policy);
- SET(pml4entry.cache_policy);
- }
- else // writeback set
- {
- CLEAR(ptentry.cache_policy);
- CLEAR(pdentry.cache_policy);
- CLEAR(pdpentry.cache_policy);
- CLEAR(pml4entry.cache_policy);
- }
- if (attrset >> 4) // Cache/No cache => no cache set
- {
- SET(ptentry.cache_disable);
- SET(pdentry.cache_disable);
- SET(pdpentry.cache_disable);
- SET(pml4entry.cache_disable);
- }
- else // cache set
- {
- CLEAR(ptentry.cache_disable);
- CLEAR(pdentry.cache_disable);
- CLEAR(pdpentry.cache_disable);
- CLEAR(pml4entry.cache_disable);
- }
- if (attrset >> 5) // No execute => no execute set
- {
- SET(ptentry.no_execute);
- SET(pdentry.no_execute);
- SET(pdpentry.no_execute);
- SET(pml4entry.no_execute);
- }
- else // execute set
- {
- CLEAR(ptentry.no_execute);
- CLEAR(pdentry.no_execute);
- CLEAR(pdpentry.no_execute);
- CLEAR(pml4entry.no_execute);
- }
- PML4tab[pml4offset] = pml4entry;
- PDPtab[pdpoffset] = pdpentry;
- PDtab[pdoffset] = pdentry;
- PTtab[ptoffset] = ptentry;
- tlbflush(PML4tab);
- tlbflush(PDPtab);
- tlbflush(PDtab);
- tlbflush(PTtab);
- memory_barrier();
- len -= EFI_PAGE_SIZE;
- size_t v_t_addr = (size_t)vaddr;
- v_t_addr += EFI_PAGE_SIZE;
- vaddr = (void*)v_t_addr;
- }
- }
- void set_paging_attributes(void* vaddr, size_t len, size_t attrset)
- {
- while (len)
- {
- uint16_t pml4offset = ((size_t)decanonical(vaddr) >> 39) & 0x1FF;
- uint16_t pdpoffset = ((size_t)decanonical(vaddr) >> 30) & 0x1FF;
- uint16_t pdoffset = ((size_t)decanonical(vaddr) >> 21) & 0x1FF;
- uint16_t ptoffset = ((size_t)decanonical(vaddr) >> 12) & 0x1FF;
- uint16_t ppoffset = (size_t)decanonical(vaddr) & 0x1FF;
- PML4entry pml4entry = PML4tab[pml4offset];
- PDPentry pdpentry = PDPtab[pdpoffset];
- PDentry pdentry = PDtab[pdoffset];
- PTentry ptentry = PTtab[ptoffset];
- pdentry.pt_addr = ((uint64_t)PTtab >> 12);
- pdpentry.pd_addr = ((uint64_t)PDtab >> 12);
- pml4entry.pdp_addr = ((uint64_t)PDPtab >> 12);
- ptentry.present, pdentry.present, pdpentry.present, pml4entry.present = 0b1; // Set the present bit
- if (attrset >> 1) //Read/write => read/write set
- {
- SET(ptentry.read_write);
- SET(pdentry.read_write);
- SET(pdpentry.read_write);
- SET(pml4entry.read_write);
- }
- else // read only set
- {
- CLEAR(ptentry.read_write);
- CLEAR(pdentry.read_write);
- CLEAR(pdpentry.read_write);
- CLEAR(pml4entry.read_write);
- }
- if (attrset >> 2) // User/Supervisor => user and supervisor set
- {
- SET(ptentry.user_supervisor);
- SET(pdentry.user_supervisor);
- SET(pdpentry.user_supervisor);
- SET(pml4entry.user_supervisor);
- }
- else // User only set
- {
- CLEAR(ptentry.user_supervisor);
- CLEAR(pdentry.user_supervisor);
- CLEAR(pdpentry.user_supervisor);
- CLEAR(pml4entry.user_supervisor);
- }
- if (attrset >> 3) // Writethrough/writeback => writethrough set
- {
- SET(ptentry.cache_policy);
- SET(pdentry.cache_policy);
- SET(pdpentry.cache_policy);
- SET(pml4entry.cache_policy);
- }
- else // writeback set
- {
- CLEAR(ptentry.cache_policy);
- CLEAR(pdentry.cache_policy);
- CLEAR(pdpentry.cache_policy);
- CLEAR(pml4entry.cache_policy);
- }
- if (attrset >> 4) // Cache/No cache => no cache set
- {
- SET(ptentry.cache_disable);
- SET(pdentry.cache_disable);
- SET(pdpentry.cache_disable);
- SET(pml4entry.cache_disable);
- }
- else // cache set
- {
- CLEAR(ptentry.cache_disable);
- CLEAR(pdentry.cache_disable);
- CLEAR(pdpentry.cache_disable);
- CLEAR(pml4entry.cache_disable);
- }
- if (attrset >> 5) // No execute => no execute set
- {
- SET(ptentry.no_execute);
- SET(pdentry.no_execute);
- SET(pdpentry.no_execute);
- SET(pml4entry.no_execute);
- }
- else // execute set
- {
- CLEAR(ptentry.no_execute);
- CLEAR(pdentry.no_execute);
- CLEAR(pdpentry.no_execute);
- CLEAR(pml4entry.no_execute);
- }
- PML4tab[pml4offset] = pml4entry;
- PDPtab[pdpoffset] = pdpentry;
- PDtab[pdoffset] = pdentry;
- PTtab[ptoffset] = ptentry;
- len -= EFI_PAGE_SIZE;
- size_t v_t_addr = (size_t)vaddr;
- v_t_addr += EFI_PAGE_SIZE;
- vaddr = (void*)v_t_addr;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement