Advertisement
Guest User

Untitled

a guest
Oct 10th, 2020
184
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.30 KB | None | 0 0
  1. #include "paging.h"
  2. #include "asm.h"
  3. #include "pfa.h"
  4. #include "bootscreen_output.h"
  5.  
  6. #define SET(field) field |= 0b1
  7. #define CLEAR(field) field &= 0b0
  8.  
  9. typedef struct {
  10.     uint8_t present : 1;
  11.     uint8_t read_write : 1;
  12.     uint8_t user_supervisor : 1;
  13.     uint8_t cache_policy : 1;
  14.     uint8_t cache_disable : 1;
  15.     uint8_t accessed : 1;
  16.     uint8_t reserved : 3; // Must be 0b000
  17.     uint8_t avl_3 : 3;
  18.     uint64_t pdp_addr : 40;
  19.     uint16_t avl_11 : 11;
  20.     uint8_t no_execute : 1;
  21. } PML4entry;
  22.  
  23. typedef struct {
  24.     uint8_t present : 1;
  25.     uint8_t read_write : 1;
  26.     uint8_t user_supervisor : 1;
  27.     uint8_t cache_policy : 1;
  28.     uint8_t cache_disable : 1;
  29.     uint8_t accessed : 1;
  30.     uint8_t mbz : 3; // Must be 0 to also ensure it corresponds to 4kb paging
  31.     uint8_t avl_3 : 3;
  32.     uint64_t pd_addr : 40;
  33.     uint16_t avl_11 : 11;
  34.     uint8_t no_execute : 1;
  35. } PDPentry;
  36.  
  37. typedef struct {
  38.     uint8_t present : 1;
  39.     uint8_t read_write : 1;
  40.     uint8_t user_supervisor : 1;
  41.     uint8_t cache_policy : 1;
  42.     uint8_t cache_disable : 1;
  43.     uint8_t accessed : 1;
  44.     uint8_t mbz : 3; // Must be 0 to also ensure it corresponds to 4kb paging
  45.     uint8_t avl_3 : 3;
  46.     uint64_t pt_addr : 40;
  47.     uint16_t avl_11 : 11;
  48.     uint8_t no_execute : 1;
  49.  
  50. } PDentry;
  51.  
  52. typedef struct {
  53.     uint8_t present : 1;
  54.     uint8_t read_write : 1;
  55.     uint8_t user_supervisor : 1;
  56.     uint8_t cache_policy : 1;
  57.     uint8_t cache_disable : 1;
  58.     uint8_t accessed : 1;
  59.     uint8_t dirty : 1;
  60.     uint8_t pat : 1;
  61.     uint8_t global : 1;
  62.     uint8_t avl_3 : 3;
  63.     uint64_t page_base_addr : 40;
  64.     uint16_t avl_11 : 11;
  65.     uint8_t no_execute : 1;
  66. } PTentry;
  67.  
  68. /* Must all be aligned on 0b1000000000000 (4096) byte boundaries*/
  69. static __declspec(align(4096)) PML4entry PML4tab[512] = { 0 }; /* Fill page tables empty; ensures reserved bits are all cleared */
  70. static __declspec(align(4096)) PDPentry PDPtab[512] = { 0 };
  71. static __declspec(align(4096)) PDentry PDtab[512] = { 0 };
  72. static __declspec(align(4096)) PTentry PTtab[512] = { 0 };
  73.  
  74. static void* make_canonical(void* addr) {
  75.     size_t naddr = (size_t)addr;
  76.     if (naddr & ((size_t)1 << 47))
  77.         naddr |= 0xFFFF000000000000;
  78.     return (void*)naddr;
  79. }
  80.  
  81. static void* decanonical(void* addr) {
  82.     return (void*)((size_t)addr & 0x0000FFFFFFFFFFFF);
  83. }
  84.  
  85. void paging_init() {
  86.     printLn("Hello");
  87.     write_cr3((void*)PML4tab);
  88.     printLn("Written pml4 table to cr3");
  89. }
  90.  
  91. void paging_map(void* vaddr, size_t len, size_t attrset)
  92. {
  93.     while (len)
  94.     {
  95.         uint16_t pml4offset = ((size_t)decanonical(vaddr) >> 39) & 0x1FF;
  96.         uint16_t pdpoffset = ((size_t)decanonical(vaddr) >> 30) & 0x1FF;
  97.         uint16_t pdoffset = ((size_t)decanonical(vaddr) >> 21) & 0x1FF;
  98.         uint16_t ptoffset = ((size_t)decanonical(vaddr) >> 12) & 0x1FF;
  99.         uint16_t ppoffset = (size_t)decanonical(vaddr) & 0x1FF;
  100.  
  101.         PML4entry pml4entry = PML4tab[pml4offset];
  102.         PDPentry pdpentry = PDPtab[pdpoffset];
  103.         PDentry pdentry = PDtab[pdoffset];
  104.         PTentry ptentry = PTtab[ptoffset];
  105.  
  106.         if (!(ptentry.present & 0x1)) {
  107.             /* Page is present, now we have to swap to the pagefile. */
  108.         }
  109.         else {
  110.             //Page is not present, make a new page.
  111.             ptentry.page_base_addr = (pfa_alloc() >> 12);
  112.         }
  113.         pdentry.pt_addr = ((uint64_t)PTtab >> 12);
  114.         pdpentry.pd_addr = ((uint64_t)PDtab >> 12);
  115.         pml4entry.pdp_addr = ((uint64_t)PDPtab >> 12);
  116.         ptentry.present, pdentry.present, pdpentry.present, pml4entry.present = 0b1; // Set the present bit
  117.  
  118.         if (attrset >> 1) //Read/write => read/write set
  119.         {
  120.             SET(ptentry.read_write);
  121.             SET(pdentry.read_write);
  122.             SET(pdpentry.read_write);
  123.             SET(pml4entry.read_write);
  124.         }
  125.         else // read only set
  126.         {
  127.             CLEAR(ptentry.read_write);
  128.             CLEAR(pdentry.read_write);
  129.             CLEAR(pdpentry.read_write);
  130.             CLEAR(pml4entry.read_write);
  131.         }
  132.         if (attrset >> 2) // User/Supervisor => user and supervisor set
  133.         {
  134.             SET(ptentry.user_supervisor);
  135.             SET(pdentry.user_supervisor);
  136.             SET(pdpentry.user_supervisor);
  137.             SET(pml4entry.user_supervisor);
  138.         }
  139.         else // User only set
  140.         {
  141.             CLEAR(ptentry.user_supervisor);
  142.             CLEAR(pdentry.user_supervisor);
  143.             CLEAR(pdpentry.user_supervisor);
  144.             CLEAR(pml4entry.user_supervisor);
  145.         }
  146.         if (attrset >> 3) // Writethrough/writeback => writethrough set
  147.         {
  148.             SET(ptentry.cache_policy);
  149.             SET(pdentry.cache_policy);
  150.             SET(pdpentry.cache_policy);
  151.             SET(pml4entry.cache_policy);
  152.         }
  153.         else // writeback set
  154.         {
  155.             CLEAR(ptentry.cache_policy);
  156.             CLEAR(pdentry.cache_policy);
  157.             CLEAR(pdpentry.cache_policy);
  158.             CLEAR(pml4entry.cache_policy);
  159.         }
  160.         if (attrset >> 4) // Cache/No cache => no cache set
  161.         {
  162.             SET(ptentry.cache_disable);
  163.             SET(pdentry.cache_disable);
  164.             SET(pdpentry.cache_disable);
  165.             SET(pml4entry.cache_disable);
  166.         }
  167.         else // cache set
  168.         {
  169.             CLEAR(ptentry.cache_disable);
  170.             CLEAR(pdentry.cache_disable);
  171.             CLEAR(pdpentry.cache_disable);
  172.             CLEAR(pml4entry.cache_disable);
  173.         }
  174.         if (attrset >> 5) // No execute => no execute set
  175.         {
  176.             SET(ptentry.no_execute);
  177.             SET(pdentry.no_execute);
  178.             SET(pdpentry.no_execute);
  179.             SET(pml4entry.no_execute);
  180.         }
  181.         else // execute set
  182.         {
  183.             CLEAR(ptentry.no_execute);
  184.             CLEAR(pdentry.no_execute);
  185.             CLEAR(pdpentry.no_execute);
  186.             CLEAR(pml4entry.no_execute);
  187.         }
  188.  
  189.         PML4tab[pml4offset] = pml4entry;
  190.         PDPtab[pdpoffset] = pdpentry;
  191.         PDtab[pdoffset] = pdentry;
  192.         PTtab[ptoffset] = ptentry;
  193.         tlbflush(PML4tab);
  194.         tlbflush(PDPtab);
  195.         tlbflush(PDtab);
  196.         tlbflush(PTtab);
  197.         memory_barrier();
  198.  
  199.         len -= EFI_PAGE_SIZE;
  200.         size_t v_t_addr = (size_t)vaddr;
  201.         v_t_addr += EFI_PAGE_SIZE;
  202.         vaddr = (void*)v_t_addr;
  203.     }
  204. }
  205.  
  206. void set_paging_attributes(void* vaddr, size_t len, size_t attrset)
  207. {
  208.     while (len)
  209.     {
  210.         uint16_t pml4offset = ((size_t)decanonical(vaddr) >> 39) & 0x1FF;
  211.         uint16_t pdpoffset = ((size_t)decanonical(vaddr) >> 30) & 0x1FF;
  212.         uint16_t pdoffset = ((size_t)decanonical(vaddr) >> 21) & 0x1FF;
  213.         uint16_t ptoffset = ((size_t)decanonical(vaddr) >> 12) & 0x1FF;
  214.         uint16_t ppoffset = (size_t)decanonical(vaddr) & 0x1FF;
  215.  
  216.         PML4entry pml4entry = PML4tab[pml4offset];
  217.         PDPentry pdpentry = PDPtab[pdpoffset];
  218.         PDentry pdentry = PDtab[pdoffset];
  219.         PTentry ptentry = PTtab[ptoffset];
  220.  
  221.         pdentry.pt_addr = ((uint64_t)PTtab >> 12);
  222.         pdpentry.pd_addr = ((uint64_t)PDtab >> 12);
  223.         pml4entry.pdp_addr = ((uint64_t)PDPtab >> 12);
  224.         ptentry.present, pdentry.present, pdpentry.present, pml4entry.present = 0b1; // Set the present bit
  225.  
  226.         if (attrset >> 1) //Read/write => read/write set
  227.         {
  228.             SET(ptentry.read_write);
  229.             SET(pdentry.read_write);
  230.             SET(pdpentry.read_write);
  231.             SET(pml4entry.read_write);
  232.         }
  233.         else // read only set
  234.         {
  235.             CLEAR(ptentry.read_write);
  236.             CLEAR(pdentry.read_write);
  237.             CLEAR(pdpentry.read_write);
  238.             CLEAR(pml4entry.read_write);
  239.         }
  240.         if (attrset >> 2) // User/Supervisor => user and supervisor set
  241.         {
  242.             SET(ptentry.user_supervisor);
  243.             SET(pdentry.user_supervisor);
  244.             SET(pdpentry.user_supervisor);
  245.             SET(pml4entry.user_supervisor);
  246.         }
  247.         else // User only set
  248.         {
  249.             CLEAR(ptentry.user_supervisor);
  250.             CLEAR(pdentry.user_supervisor);
  251.             CLEAR(pdpentry.user_supervisor);
  252.             CLEAR(pml4entry.user_supervisor);
  253.         }
  254.         if (attrset >> 3) // Writethrough/writeback => writethrough set
  255.         {
  256.             SET(ptentry.cache_policy);
  257.             SET(pdentry.cache_policy);
  258.             SET(pdpentry.cache_policy);
  259.             SET(pml4entry.cache_policy);
  260.         }
  261.         else // writeback set
  262.         {
  263.             CLEAR(ptentry.cache_policy);
  264.             CLEAR(pdentry.cache_policy);
  265.             CLEAR(pdpentry.cache_policy);
  266.             CLEAR(pml4entry.cache_policy);
  267.         }
  268.         if (attrset >> 4) // Cache/No cache => no cache set
  269.         {
  270.             SET(ptentry.cache_disable);
  271.             SET(pdentry.cache_disable);
  272.             SET(pdpentry.cache_disable);
  273.             SET(pml4entry.cache_disable);
  274.         }
  275.         else // cache set
  276.         {
  277.             CLEAR(ptentry.cache_disable);
  278.             CLEAR(pdentry.cache_disable);
  279.             CLEAR(pdpentry.cache_disable);
  280.             CLEAR(pml4entry.cache_disable);
  281.         }
  282.         if (attrset >> 5) // No execute => no execute set
  283.         {
  284.             SET(ptentry.no_execute);
  285.             SET(pdentry.no_execute);
  286.             SET(pdpentry.no_execute);
  287.             SET(pml4entry.no_execute);
  288.         }
  289.         else // execute set
  290.         {
  291.             CLEAR(ptentry.no_execute);
  292.             CLEAR(pdentry.no_execute);
  293.             CLEAR(pdpentry.no_execute);
  294.             CLEAR(pml4entry.no_execute);
  295.         }
  296.  
  297.         PML4tab[pml4offset] = pml4entry;
  298.         PDPtab[pdpoffset] = pdpentry;
  299.         PDtab[pdoffset] = pdentry;
  300.         PTtab[ptoffset] = ptentry;
  301.  
  302.         len -= EFI_PAGE_SIZE;
  303.         size_t v_t_addr = (size_t)vaddr;
  304.         v_t_addr += EFI_PAGE_SIZE;
  305.         vaddr = (void*)v_t_addr;
  306.     }
  307. }
  308.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement