Ignore:
File:
1 edited

Legend:

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

    r214ec25c r64f6ef04  
    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               
    9158                page_table_lock(AS_KERNEL, true);
    92 
     59               
    9360                /*
    9461                 * PA2KA(identity) mapping for all frames.
    9562                 */
    96                 for (cur = 0; cur < last_frame; cur += FRAME_SIZE) {
    97                         /* Standard identity mapping */
     63                for (cur = 0; cur < last_frame; cur += FRAME_SIZE)
    9864                        page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, identity_flags);
    99                 }
    10065               
    101                 /* Upper kernel mapping
    102                  * - from zero to top of kernel (include bottom addresses
    103                  *   because some are needed for init)
    104                  */
    105                 for (cur = PA2KA_CODE(0); cur < config.base + config.kernel_size; cur += FRAME_SIZE)
    106                         page_mapping_insert(AS_KERNEL, cur, KA2PA(cur), identity_flags);
     66                page_table_unlock(AS_KERNEL, true);
    10767               
    108                 for (cur = config.stack_base; cur < config.stack_base + config.stack_size; cur += FRAME_SIZE)
    109                         page_mapping_insert(AS_KERNEL, cur, KA2PA(cur), identity_flags);
    110                
    111                 for (i = 0; i < init.cnt; i++) {
    112                         for (cur = init.tasks[i].addr; cur < init.tasks[i].addr + init.tasks[i].size; cur += FRAME_SIZE)
    113                                 page_mapping_insert(AS_KERNEL, PA2KA_CODE(KA2PA(cur)), KA2PA(cur), identity_flags);
    114                 }
    115 
    116                 page_table_unlock(AS_KERNEL, true);
    117 
    11868                exc_register(14, "page_fault", true, (iroutine_t) page_fault);
    11969                write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
     
    12272}
    12373
    124 
    125 /** Identity page mapper
    126  *
    127  * We need to map whole physical memory identically before the page subsystem
    128  * is initializaed. This thing clears page table and fills in the specific
    129  * items.
    130  */
    131 void ident_page_fault(unsigned int n, istate_t *istate)
    132 {
    133         uintptr_t page;
    134         static uintptr_t oldpage = 0;
    135         pte_t *aptl_1, *aptl_2, *aptl_3;
    136 
    137         page = read_cr2();
    138         if (oldpage) {
    139                 /* Unmap old address */
    140                 aptl_1 = PTL1_ADDR(&ptl_0, oldpage);
    141                 aptl_2 = PTL2_ADDR(aptl_1, oldpage);
    142                 aptl_3 = PTL3_ADDR(aptl_2, oldpage);
    143 
    144                 SET_FRAME_FLAGS_ARCH(aptl_3, PTL3_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT);
    145                 if (KA2PA(aptl_3) == KA2PA(helper_ptl3))
    146                         SET_PTL3_FLAGS_ARCH(aptl_2, PTL2_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT);
    147                 if (KA2PA(aptl_2) == KA2PA(helper_ptl2))
    148                         SET_PTL2_FLAGS_ARCH(aptl_1, PTL1_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT);
    149                 if (KA2PA(aptl_1) == KA2PA(helper_ptl1))
    150                         SET_PTL1_FLAGS_ARCH(&ptl_0, PTL0_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT);
    151         }
    152         if (PTL1_PRESENT(&ptl_0, page))
    153                 aptl_1 = PTL1_ADDR(&ptl_0, page);
    154         else {
    155                 SETUP_PTL1(&ptl_0, page, helper_ptl1);
    156                 aptl_1 = helper_ptl1;
    157         }
    158            
    159         if (PTL2_PRESENT(aptl_1, page))
    160                 aptl_2 = PTL2_ADDR(aptl_1, page);
    161         else {
    162                 SETUP_PTL2(aptl_1, page, helper_ptl2);
    163                 aptl_2 = helper_ptl2;
    164         }
    165 
    166         if (PTL3_PRESENT(aptl_2, page))
    167                 aptl_3 = PTL3_ADDR(aptl_2, page);
    168         else {
    169                 SETUP_PTL3(aptl_2, page, helper_ptl3);
    170                 aptl_3 = helper_ptl3;
    171         }
    172        
    173         SETUP_FRAME(aptl_3, page, page);
    174 
    175         oldpage = page;
    176 }
    177 
    178 
    17974void page_fault(unsigned int n, istate_t *istate)
    18075{
    181         uintptr_t page;
    182         pf_access_t access;
    183        
    184         page = read_cr2();
     76        uintptr_t page = read_cr2();
    18577       
    18678        if (istate->error_word & PFERR_CODE_RSVD)
    18779                panic("Reserved bit set in page table entry.");
     80       
     81        pf_access_t access;
    18882       
    18983        if (istate->error_word & PFERR_CODE_RW)
     
    19589       
    19690        if (as_page_fault(page, access, istate) == AS_PF_FAULT) {
    197                 fault_if_from_uspace(istate, "Page fault: %#x.", page);
    198 
     91                fault_if_from_uspace(istate, "Page fault: %p.", page);
    19992                decode_istate(n, istate);
    200                 printf("Page fault address: %llx.\n", page);
    201                 panic("Page fault.");
     93                panic("Page fault: %p", page);
    20294        }
    20395}
    204 
    20596
    20697uintptr_t hw_map(uintptr_t physaddr, size_t size)
    20798{
    20899        if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
    209                 panic("Unable to map physical memory %p (%d bytes).", physaddr,
     100                panic("Unable to map physical memory %p (%" PRIs " bytes).", physaddr,
    210101                    size);
    211102       
    212103        uintptr_t virtaddr = PA2KA(last_frame);
    213104        pfn_t i;
    214 
     105       
    215106        page_table_lock(AS_KERNEL, true);
     107       
    216108        for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++)
    217109                page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE | PAGE_WRITE);
     110       
    218111        page_table_unlock(AS_KERNEL, true);
    219112       
Note: See TracChangeset for help on using the changeset viewer.