Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/genarch/src/mm/page_pt.c

    rcaed0279 r235e6c7  
    3939#include <mm/page.h>
    4040#include <mm/frame.h>
    41 #include <mm/km.h>
    4241#include <mm/as.h>
    4342#include <arch/mm/page.h>
     
    4645#include <arch/asm.h>
    4746#include <memstr.h>
    48 #include <align.h>
    49 #include <macros.h>
    50 #include <bitops.h>
    5147
    5248static void pt_mapping_insert(as_t *, uintptr_t, uintptr_t, unsigned int);
    5349static void pt_mapping_remove(as_t *, uintptr_t);
    5450static pte_t *pt_mapping_find(as_t *, uintptr_t, bool);
    55 static void pt_mapping_make_global(uintptr_t, size_t);
    5651
    5752page_mapping_operations_t pt_mapping_operations = {
    5853        .mapping_insert = pt_mapping_insert,
    5954        .mapping_remove = pt_mapping_remove,
    60         .mapping_find = pt_mapping_find,
    61         .mapping_make_global = pt_mapping_make_global
     55        .mapping_find = pt_mapping_find
    6256};
    6357
     
    8175       
    8276        if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT) {
    83                 pte_t *newpt = (pte_t *) frame_alloc(PTL1_SIZE,
    84                     FRAME_LOWMEM | FRAME_KA);
     77                pte_t *newpt = (pte_t *) frame_alloc(PTL1_SIZE, FRAME_KA);
    8578                memsetb(newpt, FRAME_SIZE << PTL1_SIZE, 0);
    8679                SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page), KA2PA(newpt));
    87                 SET_PTL1_FLAGS(ptl0, PTL0_INDEX(page),
    88                     PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE |
    89                     PAGE_WRITE);
     80                SET_PTL1_FLAGS(ptl0, PTL0_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE);
    9081        }
    9182       
     
    9384       
    9485        if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT) {
    95                 pte_t *newpt = (pte_t *) frame_alloc(PTL2_SIZE,
    96                     FRAME_LOWMEM | FRAME_KA);
     86                pte_t *newpt = (pte_t *) frame_alloc(PTL2_SIZE, FRAME_KA);
    9787                memsetb(newpt, FRAME_SIZE << PTL2_SIZE, 0);
    9888                SET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page), KA2PA(newpt));
    99                 SET_PTL2_FLAGS(ptl1, PTL1_INDEX(page),
    100                     PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE |
    101                     PAGE_WRITE);
     89                SET_PTL2_FLAGS(ptl1, PTL1_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE);
    10290        }
    10391       
     
    10593       
    10694        if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT) {
    107                 pte_t *newpt = (pte_t *) frame_alloc(PTL3_SIZE,
    108                     FRAME_LOWMEM | FRAME_KA);
     95                pte_t *newpt = (pte_t *) frame_alloc(PTL3_SIZE, FRAME_KA);
    10996                memsetb(newpt, FRAME_SIZE << PTL3_SIZE, 0);
    11097                SET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page), KA2PA(newpt));
    111                 SET_PTL3_FLAGS(ptl2, PTL2_INDEX(page),
    112                     PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE |
    113                     PAGE_WRITE);
     98                SET_PTL3_FLAGS(ptl2, PTL2_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE);
    11499        }
    115100       
     
    138123        /*
    139124         * First, remove the mapping, if it exists.
     125         *
    140126         */
    141127       
     
    154140        pte_t *ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
    155141       
     142        /* Destroy the mapping. Setting to PAGE_NOT_PRESENT is not sufficient. */
     143        memsetb(&ptl3[PTL3_INDEX(page)], sizeof(pte_t), 0);
     144       
    156145        /*
    157          * Destroy the mapping.
    158          * Setting to PAGE_NOT_PRESENT is not sufficient.
    159          */
    160         memsetb(&ptl3[PTL3_INDEX(page)], sizeof(pte_t), 0);
    161        
    162         /*
    163          * Second, free all empty tables along the way from PTL3 down to PTL0
    164          * except those needed for sharing the kernel non-identity mappings.
     146         * Second, free all empty tables along the way from PTL3 down to PTL0.
     147         *
    165148         */
    166149       
     
    179162                /*
    180163                 * PTL3 is empty.
    181                  * Release the frame and remove PTL3 pointer from the parent
    182                  * table.
    183                  */
     164                 * Release the frame and remove PTL3 pointer from preceding table.
     165                 *
     166                 */
     167                frame_free(KA2PA((uintptr_t) ptl3));
    184168#if (PTL2_ENTRIES != 0)
    185169                memsetb(&ptl2[PTL2_INDEX(page)], sizeof(pte_t), 0);
     
    187171                memsetb(&ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0);
    188172#else
    189                 if (km_is_non_identity(page))
    190                         return;
    191 
    192173                memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
    193174#endif
    194                 frame_free(KA2PA((uintptr_t) ptl3));
    195175        } else {
    196176                /*
     
    215195                /*
    216196                 * PTL2 is empty.
    217                  * Release the frame and remove PTL2 pointer from the parent
    218                  * table.
    219                  */
     197                 * Release the frame and remove PTL2 pointer from preceding table.
     198                 *
     199                 */
     200                frame_free(KA2PA((uintptr_t) ptl2));
    220201#if (PTL1_ENTRIES != 0)
    221202                memsetb(&ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0);
    222203#else
    223                 if (km_is_non_identity(page))
    224                         return;
    225 
    226204                memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
    227205#endif
    228                 frame_free(KA2PA((uintptr_t) ptl2));
    229206        } else {
    230207                /*
     
    250227                /*
    251228                 * PTL1 is empty.
    252                  * Release the frame and remove PTL1 pointer from the parent
    253                  * table.
    254                  */
    255                 if (km_is_non_identity(page))
    256                         return;
    257 
     229                 * Release the frame and remove PTL1 pointer from preceding table.
     230                 *
     231                 */
     232                frame_free(KA2PA((uintptr_t) ptl1));
    258233                memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
    259                 frame_free(KA2PA((uintptr_t) ptl1));
    260234        }
    261235#endif /* PTL1_ENTRIES != 0 */
     
    293267}
    294268
    295 /** Return the size of the region mapped by a single PTL0 entry.
    296  *
    297  * @return Size of the region mapped by a single PTL0 entry.
    298  */
    299 static uintptr_t ptl0_step_get(void)
    300 {
    301         size_t va_bits;
    302 
    303         va_bits = fnzb(PTL0_ENTRIES) + fnzb(PTL1_ENTRIES) + fnzb(PTL2_ENTRIES) +
    304             fnzb(PTL3_ENTRIES) + PAGE_WIDTH;
    305 
    306         return 1UL << (va_bits - fnzb(PTL0_ENTRIES));
    307 }
    308 
    309 /** Make the mappings in the given range global accross all address spaces.
    310  *
    311  * All PTL0 entries in the given range will be mapped to a next level page
    312  * table. The next level page table will be allocated and cleared.
    313  *
    314  * pt_mapping_remove() will never deallocate these page tables even when there
    315  * are no PTEs in them.
    316  *
    317  * @param as   Address space.
    318  * @param base Base address corresponding to the first PTL0 entry that will be
    319  *             altered by this function.
    320  * @param size Size in bytes defining the range of PTL0 entries that will be
    321  *             altered by this function.
    322  */
    323 void pt_mapping_make_global(uintptr_t base, size_t size)
    324 {
    325         uintptr_t ptl0 = PA2KA((uintptr_t) AS_KERNEL->genarch.page_table);
    326         uintptr_t ptl0_step = ptl0_step_get();
    327         size_t order;
    328         uintptr_t addr;
    329 
    330 #if (PTL1_ENTRIES != 0)
    331         order = PTL1_SIZE;
    332 #elif (PTL2_ENTRIES != 0)
    333         order = PTL2_SIZE;
    334 #else
    335         order = PTL3_SIZE;
    336 #endif
    337 
    338         ASSERT(size > 0);
    339 
    340         for (addr = ALIGN_DOWN(base, ptl0_step); addr - 1 < base + size - 1;
    341             addr += ptl0_step) {
    342                 uintptr_t l1;
    343 
    344                 l1 = (uintptr_t) frame_alloc(order, FRAME_KA | FRAME_LOWMEM);
    345                 memsetb((void *) l1, FRAME_SIZE << order, 0);
    346                 SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(addr), KA2PA(l1));
    347                 SET_PTL1_FLAGS(ptl0, PTL0_INDEX(addr),
    348                     PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE |
    349                     PAGE_WRITE);
    350         }
    351 }
    352 
    353269/** @}
    354270 */
Note: See TracChangeset for help on using the changeset viewer.