Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/amd64/src/mm/page.c

    rfabc883 rc15b374  
    3939#include <mm/frame.h>
    4040#include <mm/as.h>
    41 #include <arch/interrupt.h>
    4241#include <arch/asm.h>
    4342#include <config.h>
     
    4847#include <align.h>
    4948
    50 /* Definitions for identity page mapper */
    51 pte_t helper_ptl1[512] __attribute__((aligned (PAGE_SIZE)));
    52 pte_t helper_ptl2[512] __attribute__((aligned (PAGE_SIZE)));
    53 pte_t helper_ptl3[512] __attribute__((aligned (PAGE_SIZE)));
    54 extern pte_t ptl_0; /* From boot.S */
    55 
    56 #define PTL1_PRESENT(ptl0, page) (!(GET_PTL1_FLAGS_ARCH(ptl0, PTL0_INDEX_ARCH(page)) & PAGE_NOT_PRESENT))
    57 #define PTL2_PRESENT(ptl1, page) (!(GET_PTL2_FLAGS_ARCH(ptl1, PTL1_INDEX_ARCH(page)) & PAGE_NOT_PRESENT))
    58 #define PTL3_PRESENT(ptl2, page) (!(GET_PTL3_FLAGS_ARCH(ptl2, PTL2_INDEX_ARCH(page)) & PAGE_NOT_PRESENT))
    59 
    60 #define PTL1_ADDR(ptl0, page) ((pte_t *)PA2KA(GET_PTL1_ADDRESS_ARCH(ptl0, PTL0_INDEX_ARCH(page))))
    61 #define PTL2_ADDR(ptl1, page) ((pte_t *)PA2KA(GET_PTL2_ADDRESS_ARCH(ptl1, PTL1_INDEX_ARCH(page))))
    62 #define PTL3_ADDR(ptl2, page) ((pte_t *)PA2KA(GET_PTL3_ADDRESS_ARCH(ptl2, PTL2_INDEX_ARCH(page))))
    63 
    64 #define SETUP_PTL1(ptl0, page, tgt)  {  \
    65         SET_PTL1_ADDRESS_ARCH(ptl0, PTL0_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \
    66         SET_PTL1_FLAGS_ARCH(ptl0, PTL0_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \
    67     }
    68 #define SETUP_PTL2(ptl1, page, tgt)  {  \
    69         SET_PTL2_ADDRESS_ARCH(ptl1, PTL1_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \
    70         SET_PTL2_FLAGS_ARCH(ptl1, PTL1_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \
    71     }
    72 #define SETUP_PTL3(ptl2, page, tgt)  {  \
    73         SET_PTL3_ADDRESS_ARCH(ptl2, PTL2_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \
    74         SET_PTL3_FLAGS_ARCH(ptl2, PTL2_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \
    75     }
    76 #define SETUP_FRAME(ptl3, page, tgt)  { \
    77         SET_FRAME_ADDRESS_ARCH(ptl3, PTL3_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \
    78         SET_FRAME_FLAGS_ARCH(ptl3, PTL3_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \
    79     }
    80 
    81 
    8249void page_arch_init(void)
    8350{
    84         uintptr_t cur;
    85         unsigned int i;
    86         int identity_flags = PAGE_CACHEABLE | PAGE_EXEC | PAGE_GLOBAL | PAGE_WRITE;
    87 
    8851        if (config.cpu_active == 1) {
     52                uintptr_t cur;
     53                unsigned int identity_flags =
     54                    PAGE_CACHEABLE | PAGE_EXEC | PAGE_GLOBAL | PAGE_WRITE;
     55               
    8956                page_mapping_operations = &pt_mapping_operations;
    90 
     57               
     58                page_table_lock(AS_KERNEL, true);
     59               
    9160                /*
    9261                 * PA2KA(identity) mapping for all frames.
    9362                 */
    94                 for (cur = 0; cur < last_frame; cur += FRAME_SIZE) {
    95                         /* Standard identity mapping */
     63                for (cur = 0; cur < last_frame; cur += FRAME_SIZE)
    9664                        page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, identity_flags);
    97                 }
    9865               
    99                 /* Upper kernel mapping
    100                  * - from zero to top of kernel (include bottom addresses
    101                  *   because some are needed for init)
    102                  */
    103                 for (cur = PA2KA_CODE(0); cur < config.base + config.kernel_size; cur += FRAME_SIZE)
    104                         page_mapping_insert(AS_KERNEL, cur, KA2PA(cur), identity_flags);
     66                page_table_unlock(AS_KERNEL, true);
    10567               
    106                 for (cur = config.stack_base; cur < config.stack_base + config.stack_size; cur += FRAME_SIZE)
    107                         page_mapping_insert(AS_KERNEL, cur, KA2PA(cur), identity_flags);
    108                
    109                 for (i = 0; i < init.cnt; i++) {
    110                         for (cur = init.tasks[i].addr; cur < init.tasks[i].addr + init.tasks[i].size; cur += FRAME_SIZE)
    111                                 page_mapping_insert(AS_KERNEL, PA2KA_CODE(KA2PA(cur)), KA2PA(cur), identity_flags);
    112                 }
    113 
    114                 exc_register(14, "page_fault", (iroutine) page_fault);
     68                exc_register(14, "page_fault", true, (iroutine_t) page_fault);
    11569                write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
    116         } else 
     70        } else
    11771                write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
    11872}
    11973
    120 
    121 /** Identity page mapper
    122  *
    123  * We need to map whole physical memory identically before the page subsystem
    124  * is initializaed. This thing clears page table and fills in the specific
    125  * items.
    126  */
    127 void ident_page_fault(int n, istate_t *istate)
     74void page_fault(unsigned int n, istate_t *istate)
    12875{
    129         uintptr_t page;
    130         static uintptr_t oldpage = 0;
    131         pte_t *aptl_1, *aptl_2, *aptl_3;
    132 
    133         page = read_cr2();
    134         if (oldpage) {
    135                 /* Unmap old address */
    136                 aptl_1 = PTL1_ADDR(&ptl_0, oldpage);
    137                 aptl_2 = PTL2_ADDR(aptl_1, oldpage);
    138                 aptl_3 = PTL3_ADDR(aptl_2, oldpage);
    139 
    140                 SET_FRAME_FLAGS_ARCH(aptl_3, PTL3_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT);
    141                 if (KA2PA(aptl_3) == KA2PA(helper_ptl3))
    142                         SET_PTL3_FLAGS_ARCH(aptl_2, PTL2_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT);
    143                 if (KA2PA(aptl_2) == KA2PA(helper_ptl2))
    144                         SET_PTL2_FLAGS_ARCH(aptl_1, PTL1_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT);
    145                 if (KA2PA(aptl_1) == KA2PA(helper_ptl1))
    146                         SET_PTL1_FLAGS_ARCH(&ptl_0, PTL0_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT);
    147         }
    148         if (PTL1_PRESENT(&ptl_0, page))
    149                 aptl_1 = PTL1_ADDR(&ptl_0, page);
    150         else {
    151                 SETUP_PTL1(&ptl_0, page, helper_ptl1);
    152                 aptl_1 = helper_ptl1;
    153         }
    154            
    155         if (PTL2_PRESENT(aptl_1, page))
    156                 aptl_2 = PTL2_ADDR(aptl_1, page);
    157         else {
    158                 SETUP_PTL2(aptl_1, page, helper_ptl2);
    159                 aptl_2 = helper_ptl2;
    160         }
    161 
    162         if (PTL3_PRESENT(aptl_2, page))
    163                 aptl_3 = PTL3_ADDR(aptl_2, page);
    164         else {
    165                 SETUP_PTL3(aptl_2, page, helper_ptl3);
    166                 aptl_3 = helper_ptl3;
    167         }
    168        
    169         SETUP_FRAME(aptl_3, page, page);
    170 
    171         oldpage = page;
    172 }
    173 
    174 
    175 void page_fault(int n, istate_t *istate)
    176 {
    177         uintptr_t page;
    178         pf_access_t access;
    179        
    180         page = read_cr2();
     76        uintptr_t page = read_cr2();
    18177       
    18278        if (istate->error_word & PFERR_CODE_RSVD)
    18379                panic("Reserved bit set in page table entry.");
     80       
     81        pf_access_t access;
    18482       
    18583        if (istate->error_word & PFERR_CODE_RW)
     
    19290        if (as_page_fault(page, access, istate) == AS_PF_FAULT) {
    19391                fault_if_from_uspace(istate, "Page fault: %#x.", page);
    194 
    195                 decode_istate(n, istate);
    196                 printf("Page fault address: %llx.\n", page);
    197                 panic("Page fault.");
     92                panic_memtrap(istate, access, page, NULL);
    19893        }
    19994}
    200 
    20195
    20296uintptr_t hw_map(uintptr_t physaddr, size_t size)
    20397{
    20498        if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
    205                 panic("Unable to map physical memory %p (%d bytes).", physaddr,
     99                panic("Unable to map physical memory %p (%" PRIs " bytes).", physaddr,
    206100                    size);
    207101       
    208102        uintptr_t virtaddr = PA2KA(last_frame);
    209103        pfn_t i;
     104       
     105        page_table_lock(AS_KERNEL, true);
     106       
    210107        for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++)
    211108                page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE | PAGE_WRITE);
     109       
     110        page_table_unlock(AS_KERNEL, true);
    212111       
    213112        last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
Note: See TracChangeset for help on using the changeset viewer.