Changeset a1f60f3 in mainline for kernel/arch/amd64/src/mm


Ignore:
Timestamp:
2010-06-27T23:04:20Z (16 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
64f6ef04
Parents:
33dac7d
Message:

move from "kernel" memory model to "large" memory model
get rid of the extra identity mapping of the physical memory at -2 GB

File:
1 edited

Legend:

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

    r33dac7d ra1f60f3  
    5252pte_t helper_ptl2[512] __attribute__((aligned (PAGE_SIZE)));
    5353pte_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 
     54
     55static uintptr_t oldpage = 0;
     56
     57extern pte_t ptl_0;  /* From boot.S */
     58
     59#define PTL1_PRESENT(ptl0, page) \
     60        (!(GET_PTL1_FLAGS_ARCH(ptl0, PTL0_INDEX_ARCH(page)) & PAGE_NOT_PRESENT))
     61
     62#define PTL2_PRESENT(ptl1, page) \
     63        (!(GET_PTL2_FLAGS_ARCH(ptl1, PTL1_INDEX_ARCH(page)) & PAGE_NOT_PRESENT))
     64
     65#define PTL3_PRESENT(ptl2, page) \
     66        (!(GET_PTL3_FLAGS_ARCH(ptl2, PTL2_INDEX_ARCH(page)) & PAGE_NOT_PRESENT))
     67
     68#define PTL1_ADDR(ptl0, page) \
     69        ((pte_t *) PA2KA(GET_PTL1_ADDRESS_ARCH(ptl0, PTL0_INDEX_ARCH(page))))
     70
     71#define PTL2_ADDR(ptl1, page) \
     72        ((pte_t *) PA2KA(GET_PTL2_ADDRESS_ARCH(ptl1, PTL1_INDEX_ARCH(page))))
     73
     74#define PTL3_ADDR(ptl2, page) \
     75        ((pte_t *) PA2KA(GET_PTL3_ADDRESS_ARCH(ptl2, PTL2_INDEX_ARCH(page))))
     76
     77#define SETUP_PTL1(ptl0, page, tgt) \
     78        { \
     79                SET_PTL1_ADDRESS_ARCH(ptl0, PTL0_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \
     80                SET_PTL1_FLAGS_ARCH(ptl0, PTL0_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \
     81        }
     82
     83#define SETUP_PTL2(ptl1, page, tgt) \
     84        { \
     85                SET_PTL2_ADDRESS_ARCH(ptl1, PTL1_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \
     86                SET_PTL2_FLAGS_ARCH(ptl1, PTL1_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \
     87        }
     88
     89#define SETUP_PTL3(ptl2, page, tgt) \
     90        { \
     91                SET_PTL3_ADDRESS_ARCH(ptl2, PTL2_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \
     92                SET_PTL3_FLAGS_ARCH(ptl2, PTL2_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \
     93        }
     94
     95#define SETUP_FRAME(ptl3, page, tgt) \
     96        { \
     97                SET_FRAME_ADDRESS_ARCH(ptl3, PTL3_INDEX_ARCH(page), (uintptr_t)KA2PA(tgt)); \
     98                SET_FRAME_FLAGS_ARCH(ptl3, PTL3_INDEX_ARCH(page), PAGE_WRITE | PAGE_EXEC); \
     99        }
    81100
    82101void page_arch_init(void)
    83102{
    84         uintptr_t cur;
    85         unsigned int i;
    86         int identity_flags = PAGE_CACHEABLE | PAGE_EXEC | PAGE_GLOBAL | PAGE_WRITE;
    87 
    88103        if (config.cpu_active == 1) {
     104                uintptr_t cur;
     105                unsigned int identity_flags =
     106                    PAGE_CACHEABLE | PAGE_EXEC | PAGE_GLOBAL | PAGE_WRITE;
     107               
    89108                page_mapping_operations = &pt_mapping_operations;
    90 
     109               
    91110                page_table_lock(AS_KERNEL, true);
    92 
     111               
    93112                /*
    94113                 * PA2KA(identity) mapping for all frames.
    95114                 */
    96                 for (cur = 0; cur < last_frame; cur += FRAME_SIZE) {
    97                         /* Standard identity mapping */
     115                for (cur = 0; cur < last_frame; cur += FRAME_SIZE)
    98116                        page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, identity_flags);
    99                 }
    100                
    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);
    107                
    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 
     117               
    116118                page_table_unlock(AS_KERNEL, true);
    117 
     119               
    118120                exc_register(14, "page_fault", true, (iroutine_t) page_fault);
    119121                write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
     
    122124}
    123125
    124 
    125126/** Identity page mapper
    126127 *
     
    128129 * is initializaed. This thing clears page table and fills in the specific
    129130 * items.
     131 *
    130132 */
    131133void ident_page_fault(unsigned int n, istate_t *istate)
    132134{
    133         uintptr_t page;
    134         static uintptr_t oldpage = 0;
    135         pte_t *aptl_1, *aptl_2, *aptl_3;
    136 
    137         page = read_cr2();
     135        pte_t *aptl_1;
     136        pte_t *aptl_2;
     137        pte_t *aptl_3;
     138       
     139        uintptr_t page = read_cr2();
     140       
     141        /* Unmap old address */
    138142        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 
     143                pte_t *aptl_1 = PTL1_ADDR(&ptl_0, oldpage);
     144                pte_t *aptl_2 = PTL2_ADDR(aptl_1, oldpage);
     145                pte_t *aptl_3 = PTL3_ADDR(aptl_2, oldpage);
     146               
    144147                SET_FRAME_FLAGS_ARCH(aptl_3, PTL3_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT);
     148               
    145149                if (KA2PA(aptl_3) == KA2PA(helper_ptl3))
    146150                        SET_PTL3_FLAGS_ARCH(aptl_2, PTL2_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT);
     151               
    147152                if (KA2PA(aptl_2) == KA2PA(helper_ptl2))
    148153                        SET_PTL2_FLAGS_ARCH(aptl_1, PTL1_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT);
     154               
    149155                if (KA2PA(aptl_1) == KA2PA(helper_ptl1))
    150156                        SET_PTL1_FLAGS_ARCH(&ptl_0, PTL0_INDEX_ARCH(oldpage), PAGE_NOT_PRESENT);
    151157        }
     158       
    152159        if (PTL1_PRESENT(&ptl_0, page))
    153160                aptl_1 = PTL1_ADDR(&ptl_0, page);
     
    156163                aptl_1 = helper_ptl1;
    157164        }
    158            
     165       
    159166        if (PTL2_PRESENT(aptl_1, page))
    160167                aptl_2 = PTL2_ADDR(aptl_1, page);
     
    163170                aptl_2 = helper_ptl2;
    164171        }
    165 
     172       
    166173        if (PTL3_PRESENT(aptl_2, page))
    167174                aptl_3 = PTL3_ADDR(aptl_2, page);
     
    172179       
    173180        SETUP_FRAME(aptl_3, page, page);
    174 
     181       
    175182        oldpage = page;
    176183}
    177184
    178 
    179185void page_fault(unsigned int n, istate_t *istate)
    180186{
    181         uintptr_t page;
    182         pf_access_t access;
    183        
    184         page = read_cr2();
     187        uintptr_t page = read_cr2();
    185188       
    186189        if (istate->error_word & PFERR_CODE_RSVD)
    187190                panic("Reserved bit set in page table entry.");
     191       
     192        pf_access_t access;
    188193       
    189194        if (istate->error_word & PFERR_CODE_RW)
     
    195200       
    196201        if (as_page_fault(page, access, istate) == AS_PF_FAULT) {
    197                 fault_if_from_uspace(istate, "Page fault: %#x.", page);
    198 
     202                fault_if_from_uspace(istate, "Page fault: %p.", page);
    199203                decode_istate(n, istate);
    200                 printf("Page fault address: %llx.\n", page);
    201                 panic("Page fault.");
    202         }
    203 }
    204 
     204                panic("Page fault: %p", page);
     205        }
     206}
    205207
    206208uintptr_t hw_map(uintptr_t physaddr, size_t size)
    207209{
    208210        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,
     211                panic("Unable to map physical memory %p (%" PRIs " bytes).", physaddr,
    210212                    size);
    211213       
    212214        uintptr_t virtaddr = PA2KA(last_frame);
    213215        pfn_t i;
    214 
     216       
    215217        page_table_lock(AS_KERNEL, true);
     218       
    216219        for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++)
    217220                page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE | PAGE_WRITE);
     221       
    218222        page_table_unlock(AS_KERNEL, true);
    219223       
Note: See TracChangeset for help on using the changeset viewer.