Ignore:
File:
1 edited

Legend:

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

    rd99c1d2 r8f80c77  
    3333/**
    3434 * @file
    35  * @brief       Virtual Address Translation for hierarchical 4-level page tables.
     35 * @brief Virtual Address Translation for hierarchical 4-level page tables.
    3636 */
    3737
     
    4646#include <memstr.h>
    4747
    48 static void pt_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame, int flags);
    49 static void pt_mapping_remove(as_t *as, uintptr_t page);
    50 static pte_t *pt_mapping_find(as_t *as, uintptr_t page);
     48static void pt_mapping_insert(as_t *, uintptr_t, uintptr_t, unsigned int);
     49static void pt_mapping_remove(as_t *, uintptr_t);
     50static pte_t *pt_mapping_find(as_t *, uintptr_t);
    5151
    5252page_mapping_operations_t pt_mapping_operations = {
     
    6161 * using flags.
    6262 *
    63  * The page table must be locked and interrupts must be disabled.
    64  *
    65  * @param as Address space to wich page belongs.
    66  * @param page Virtual address of the page to be mapped.
     63 * @param as    Address space to wich page belongs.
     64 * @param page  Virtual address of the page to be mapped.
    6765 * @param frame Physical address of memory frame to which the mapping is done.
    6866 * @param flags Flags to be used for mapping.
    69  */
    70 void pt_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame, int flags)
     67 *
     68 */
     69void pt_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame,
     70    unsigned int flags)
    7171{
    72         pte_t *ptl0, *ptl1, *ptl2, *ptl3;
    73         pte_t *newpt;
    74 
    75         ptl0 = (pte_t *) PA2KA((uintptr_t) as->genarch.page_table);
    76 
     72        pte_t *ptl0 = (pte_t *) PA2KA((uintptr_t) as->genarch.page_table);
     73
     74        ASSERT(interrupts_disabled());
     75        ASSERT(page_table_locked(as));
     76       
    7777        if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT) {
    78                 newpt = (pte_t *)frame_alloc(PTL1_SIZE, FRAME_KA);
     78                pte_t *newpt = (pte_t *) frame_alloc(PTL1_SIZE, FRAME_KA);
    7979                memsetb(newpt, FRAME_SIZE << PTL1_SIZE, 0);
    8080                SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page), KA2PA(newpt));
    8181                SET_PTL1_FLAGS(ptl0, PTL0_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE);
    8282        }
    83 
    84         ptl1 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page)));
    85 
     83       
     84        pte_t *ptl1 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page)));
     85       
    8686        if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT) {
    87                 newpt = (pte_t *)frame_alloc(PTL2_SIZE, FRAME_KA);
     87                pte_t *newpt = (pte_t *) frame_alloc(PTL2_SIZE, FRAME_KA);
    8888                memsetb(newpt, FRAME_SIZE << PTL2_SIZE, 0);
    8989                SET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page), KA2PA(newpt));
    9090                SET_PTL2_FLAGS(ptl1, PTL1_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE);
    9191        }
    92 
    93         ptl2 = (pte_t *) PA2KA(GET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page)));
    94 
     92       
     93        pte_t *ptl2 = (pte_t *) PA2KA(GET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page)));
     94       
    9595        if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT) {
    96                 newpt = (pte_t *)frame_alloc(PTL3_SIZE, FRAME_KA);
     96                pte_t *newpt = (pte_t *) frame_alloc(PTL3_SIZE, FRAME_KA);
    9797                memsetb(newpt, FRAME_SIZE << PTL3_SIZE, 0);
    9898                SET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page), KA2PA(newpt));
    9999                SET_PTL3_FLAGS(ptl2, PTL2_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE);
    100100        }
    101 
    102         ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
    103 
     101       
     102        pte_t *ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
     103       
    104104        SET_FRAME_ADDRESS(ptl3, PTL3_INDEX(page), frame);
    105105        SET_FRAME_FLAGS(ptl3, PTL3_INDEX(page), flags);
     
    114114 * Empty page tables except PTL0 are freed.
    115115 *
    116  * The page table must be locked and interrupts must be disabled.
    117  *
    118  * @param as Address space to wich page belongs.
     116 * @param as   Address space to wich page belongs.
    119117 * @param page Virtual address of the page to be demapped.
     118 *
    120119 */
    121120void pt_mapping_remove(as_t *as, uintptr_t page)
    122121{
    123         pte_t *ptl0, *ptl1, *ptl2, *ptl3;
    124         bool empty = true;
    125         int i;
     122        ASSERT(interrupts_disabled());
     123        ASSERT(page_table_locked(as));
    126124
    127125        /*
    128126         * First, remove the mapping, if it exists.
     127         *
    129128         */
    130 
    131         ptl0 = (pte_t *) PA2KA((uintptr_t) as->genarch.page_table);
    132 
     129       
     130        pte_t *ptl0 = (pte_t *) PA2KA((uintptr_t) as->genarch.page_table);
    133131        if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT)
    134132                return;
    135 
    136         ptl1 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page)));
    137 
     133       
     134        pte_t *ptl1 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page)));
    138135        if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT)
    139136                return;
    140 
    141         ptl2 = (pte_t *) PA2KA(GET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page)));
    142 
     137       
     138        pte_t *ptl2 = (pte_t *) PA2KA(GET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page)));
    143139        if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT)
    144140                return;
    145 
    146         ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
    147 
     141       
     142        pte_t *ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
     143       
    148144        /* Destroy the mapping. Setting to PAGE_NOT_PRESENT is not sufficient. */
    149145        memsetb(&ptl3[PTL3_INDEX(page)], sizeof(pte_t), 0);
    150 
     146       
    151147        /*
    152148         * Second, free all empty tables along the way from PTL3 down to PTL0.
     149         *
    153150         */
    154151       
    155         /* check PTL3 */
     152        /* Check PTL3 */
     153        bool empty = true;
     154       
     155        unsigned int i;
    156156        for (i = 0; i < PTL3_ENTRIES; i++) {
    157157                if (PTE_VALID(&ptl3[i])) {
     
    160160                }
    161161        }
     162       
    162163        if (empty) {
    163164                /*
    164165                 * PTL3 is empty.
    165166                 * Release the frame and remove PTL3 pointer from preceding table.
     167                 *
    166168                 */
    167169                frame_free(KA2PA((uintptr_t) ptl3));
    168                 if (PTL2_ENTRIES)
    169                         memsetb(&ptl2[PTL2_INDEX(page)], sizeof(pte_t), 0);
    170                 else if (PTL1_ENTRIES)
    171                         memsetb(&ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0);
    172                 else
    173                         memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
     170#if (PTL2_ENTRIES != 0)
     171                memsetb(&ptl2[PTL2_INDEX(page)], sizeof(pte_t), 0);
     172#elif (PTL1_ENTRIES != 0)
     173                memsetb(&ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0);
     174#else
     175                memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
     176#endif
    174177        } else {
    175178                /*
     
    177180                 * Therefore, there must be a path from PTL0 to PTL3 and
    178181                 * thus nothing to free in higher levels.
    179                  */
    180                 return;
    181         }
    182        
    183         /* check PTL2, empty is still true */
    184         if (PTL2_ENTRIES) {
    185                 for (i = 0; i < PTL2_ENTRIES; i++) {
    186                         if (PTE_VALID(&ptl2[i])) {
    187                                 empty = false;
    188                                 break;
    189                         }
     182                 *
     183                 */
     184                return;
     185        }
     186       
     187        /* Check PTL2, empty is still true */
     188#if (PTL2_ENTRIES != 0)
     189        for (i = 0; i < PTL2_ENTRIES; i++) {
     190                if (PTE_VALID(&ptl2[i])) {
     191                        empty = false;
     192                        break;
    190193                }
    191                 if (empty) {
    192                         /*
    193                          * PTL2 is empty.
    194                          * Release the frame and remove PTL2 pointer from preceding table.
    195                          */
    196                         frame_free(KA2PA((uintptr_t) ptl2));
    197                         if (PTL1_ENTRIES)
    198                                 memsetb(&ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0);
    199                         else
    200                                 memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
     194        }
     195       
     196        if (empty) {
     197                /*
     198                 * PTL2 is empty.
     199                 * Release the frame and remove PTL2 pointer from preceding table.
     200                 *
     201                 */
     202                frame_free(KA2PA((uintptr_t) ptl2));
     203#if (PTL1_ENTRIES != 0)
     204                memsetb(&ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0);
     205#else
     206                memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
     207#endif
     208        } else {
     209                /*
     210                 * PTL2 is not empty.
     211                 * Therefore, there must be a path from PTL0 to PTL2 and
     212                 * thus nothing to free in higher levels.
     213                 *
     214                 */
     215                return;
     216        }
     217#endif /* PTL2_ENTRIES != 0 */
     218       
     219        /* check PTL1, empty is still true */
     220#if (PTL1_ENTRIES != 0)
     221        for (i = 0; i < PTL1_ENTRIES; i++) {
     222                if (PTE_VALID(&ptl1[i])) {
     223                        empty = false;
     224                        break;
    201225                }
    202                 else {
    203                         /*
    204                          * PTL2 is not empty.
    205                          * Therefore, there must be a path from PTL0 to PTL2 and
    206                          * thus nothing to free in higher levels.
    207                          */
    208                         return;
    209                 }
    210         }
    211 
    212         /* check PTL1, empty is still true */
    213         if (PTL1_ENTRIES) {
    214                 for (i = 0; i < PTL1_ENTRIES; i++) {
    215                         if (PTE_VALID(&ptl1[i])) {
    216                                 empty = false;
    217                                 break;
    218                         }
    219                 }
    220                 if (empty) {
    221                         /*
    222                          * PTL1 is empty.
    223                          * Release the frame and remove PTL1 pointer from preceding table.
    224                          */
    225                         frame_free(KA2PA((uintptr_t) ptl1));
    226                         memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
    227                 }
    228         }
    229 
     226        }
     227       
     228        if (empty) {
     229                /*
     230                 * PTL1 is empty.
     231                 * Release the frame and remove PTL1 pointer from preceding table.
     232                 *
     233                 */
     234                frame_free(KA2PA((uintptr_t) ptl1));
     235                memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
     236        }
     237#endif /* PTL1_ENTRIES != 0 */
    230238}
    231239
     
    234242 * Find mapping for virtual page.
    235243 *
    236  * The page table must be locked and interrupts must be disabled.
    237  *
    238  * @param as Address space to which page belongs.
     244 * @param as   Address space to which page belongs.
    239245 * @param page Virtual page.
    240246 *
    241  * @return NULL if there is no such mapping; entry from PTL3 describing the mapping otherwise.
     247 * @return NULL if there is no such mapping; entry from PTL3 describing
     248 *         the mapping otherwise.
     249 *
    242250 */
    243251pte_t *pt_mapping_find(as_t *as, uintptr_t page)
    244252{
    245         pte_t *ptl0, *ptl1, *ptl2, *ptl3;
    246 
    247         ptl0 = (pte_t *) PA2KA((uintptr_t) as->genarch.page_table);
    248 
     253        ASSERT(interrupts_disabled());
     254        ASSERT(page_table_locked(as));
     255
     256        pte_t *ptl0 = (pte_t *) PA2KA((uintptr_t) as->genarch.page_table);
    249257        if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT)
    250258                return NULL;
    251 
    252         ptl1 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page)));
    253 
     259       
     260        pte_t *ptl1 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page)));
    254261        if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT)
    255262                return NULL;
    256 
    257         ptl2 = (pte_t *) PA2KA(GET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page)));
    258 
     263       
     264        pte_t *ptl2 = (pte_t *) PA2KA(GET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page)));
    259265        if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT)
    260266                return NULL;
    261 
    262         ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
    263 
     267       
     268        pte_t *ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
     269       
    264270        return &ptl3[PTL3_INDEX(page)];
    265271}
Note: See TracChangeset for help on using the changeset viewer.