Ignore:
File:
1 edited

Legend:

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

    rd99c1d2 r8f80c77  
    3333/**
    3434 * @file
    35  * @brief       Virtual Address Translation (VAT) for global page hash table.
     35 * @brief Virtual Address Translation (VAT) for global page hash table.
    3636 */
    3737
     
    5252#include <align.h>
    5353
    54 static size_t hash(unative_t key[]);
    55 static bool compare(unative_t key[], size_t keys, link_t *item);
    56 static void remove_callback(link_t *item);
    57 
    58 static void ht_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame,
    59     int flags);
    60 static void ht_mapping_remove(as_t *as, uintptr_t page);
    61 static pte_t *ht_mapping_find(as_t *as, uintptr_t page);
     54static size_t hash(unative_t[]);
     55static bool compare(unative_t[], size_t, link_t *);
     56static void remove_callback(link_t *);
     57
     58static void ht_mapping_insert(as_t *, uintptr_t, uintptr_t, unsigned int);
     59static void ht_mapping_remove(as_t *, uintptr_t);
     60static pte_t *ht_mapping_find(as_t *, uintptr_t);
    6261
    6362/**
     
    6564 * after address space lock and after any address space area
    6665 * locks.
     66 *
    6767 */
    6868mutex_t page_ht_lock;
    6969
    70 /**
    71  * Page hash table.
     70/** Page hash table.
     71 *
    7272 * The page hash table may be accessed only when page_ht_lock is held.
     73 *
    7374 */
    7475hash_table_t page_ht;
     
    9394 *
    9495 * @return Index into page hash table.
     96 *
    9597 */
    9698size_t hash(unative_t key[])
     
    98100        as_t *as = (as_t *) key[KEY_AS];
    99101        uintptr_t page = (uintptr_t) key[KEY_PAGE];
    100         size_t index;
    101102       
    102103        /*
     
    104105         * of occurring. Least significant bits of VPN compose the
    105106         * hash index.
    106          */
    107         index = ((page >> PAGE_WIDTH) & (PAGE_HT_ENTRIES - 1));
     107         *
     108         */
     109        size_t index = ((page >> PAGE_WIDTH) & (PAGE_HT_ENTRIES - 1));
    108110       
    109111        /*
     
    111113         * similar addresses. Least significant bits compose the
    112114         * hash index.
     115         *
    113116         */
    114117        index |= ((unative_t) as) & (PAGE_HT_ENTRIES - 1);
     
    119122/** Compare page hash table item with page and/or address space.
    120123 *
    121  * @param key Array of one or two keys (i.e. page and/or address space).
     124 * @param key  Array of one or two keys (i.e. page and/or address space).
    122125 * @param keys Number of keys passed.
    123126 * @param item Item to compare the keys with.
    124127 *
    125128 * @return true on match, false otherwise.
     129 *
    126130 */
    127131bool compare(unative_t key[], size_t keys, link_t *item)
    128132{
    129         pte_t *t;
    130 
    131133        ASSERT(item);
    132         ASSERT((keys > 0) && (keys <= PAGE_HT_KEYS));
    133 
     134        ASSERT(keys > 0);
     135        ASSERT(keys <= PAGE_HT_KEYS);
     136       
    134137        /*
    135138         * Convert item to PTE.
    136          */
    137         t = hash_table_get_instance(item, pte_t, link);
    138 
    139         if (keys == PAGE_HT_KEYS) {
    140                 return (key[KEY_AS] == (uintptr_t) t->as) &&
    141                     (key[KEY_PAGE] == t->page);
    142         } else {
    143                 return (key[KEY_AS] == (uintptr_t) t->as);
    144         }
     139         *
     140         */
     141        pte_t *pte = hash_table_get_instance(item, pte_t, link);
     142       
     143        if (keys == PAGE_HT_KEYS)
     144                return (key[KEY_AS] == (uintptr_t) pte->as) &&
     145                    (key[KEY_PAGE] == pte->page);
     146       
     147        return (key[KEY_AS] == (uintptr_t) pte->as);
    145148}
    146149
     
    148151 *
    149152 * @param item Page hash table item being removed.
     153 *
    150154 */
    151155void remove_callback(link_t *item)
    152156{
    153         pte_t *t;
    154 
    155157        ASSERT(item);
    156 
     158       
    157159        /*
    158160         * Convert item to PTE.
    159          */
    160         t = hash_table_get_instance(item, pte_t, link);
    161 
    162         free(t);
     161         *
     162         */
     163        pte_t *pte = hash_table_get_instance(item, pte_t, link);
     164       
     165        free(pte);
    163166}
    164167
     
    166169 *
    167170 * Map virtual address page to physical address frame
    168  * using flags.
    169  *
    170  * The page table must be locked and interrupts must be disabled.
    171  *
    172  * @param as Address space to which page belongs.
    173  * @param page Virtual address of the page to be mapped.
     171 * using flags.
     172 *
     173 * @param as    Address space to which page belongs.
     174 * @param page  Virtual address of the page to be mapped.
    174175 * @param frame Physical address of memory frame to which the mapping is done.
    175176 * @param flags Flags to be used for mapping.
    176  */
    177 void ht_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame, int flags)
    178 {
    179         pte_t *t;
     177 *
     178 */
     179void ht_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame,
     180    unsigned int flags)
     181{
    180182        unative_t key[2] = {
    181183                (uintptr_t) as,
    182184                page = ALIGN_DOWN(page, PAGE_SIZE)
    183185        };
     186
     187        ASSERT(interrupts_disabled());
     188        ASSERT(page_table_locked(as));
    184189       
    185190        if (!hash_table_find(&page_ht, key)) {
    186                 t = (pte_t *) malloc(sizeof(pte_t), FRAME_ATOMIC);
    187                 ASSERT(t != NULL);
    188 
    189                 t->g = (flags & PAGE_GLOBAL) != 0;
    190                 t->x = (flags & PAGE_EXEC) != 0;
    191                 t->w = (flags & PAGE_WRITE) != 0;
    192                 t->k = !(flags & PAGE_USER);
    193                 t->c = (flags & PAGE_CACHEABLE) != 0;
    194                 t->p = !(flags & PAGE_NOT_PRESENT);
    195                 t->a = false;
    196                 t->d = false;
    197 
    198                 t->as = as;
    199                 t->page = ALIGN_DOWN(page, PAGE_SIZE);
    200                 t->frame = ALIGN_DOWN(frame, FRAME_SIZE);
    201 
    202                 hash_table_insert(&page_ht, key, &t->link);
     191                pte_t *pte = (pte_t *) malloc(sizeof(pte_t), FRAME_ATOMIC);
     192                ASSERT(pte != NULL);
     193               
     194                pte->g = (flags & PAGE_GLOBAL) != 0;
     195                pte->x = (flags & PAGE_EXEC) != 0;
     196                pte->w = (flags & PAGE_WRITE) != 0;
     197                pte->k = !(flags & PAGE_USER);
     198                pte->c = (flags & PAGE_CACHEABLE) != 0;
     199                pte->p = !(flags & PAGE_NOT_PRESENT);
     200                pte->a = false;
     201                pte->d = false;
     202               
     203                pte->as = as;
     204                pte->page = ALIGN_DOWN(page, PAGE_SIZE);
     205                pte->frame = ALIGN_DOWN(frame, FRAME_SIZE);
     206               
     207                hash_table_insert(&page_ht, key, &pte->link);
    203208        }
    204209}
     
    210215 * this call visible.
    211216 *
    212  * The page table must be locked and interrupts must be disabled.
    213  *
    214  * @param as Address space to wich page belongs.
     217 * @param as   Address space to wich page belongs.
    215218 * @param page Virtual address of the page to be demapped.
     219 *
    216220 */
    217221void ht_mapping_remove(as_t *as, uintptr_t page)
     
    221225                page = ALIGN_DOWN(page, PAGE_SIZE)
    222226        };
     227
     228        ASSERT(interrupts_disabled());
     229        ASSERT(page_table_locked(as));
    223230       
    224231        /*
     
    234241 * Find mapping for virtual page.
    235242 *
    236  * The page table must be locked and interrupts must be disabled.
    237  *
    238  * @param as Address space to wich page belongs.
     243 * @param as   Address space to wich page belongs.
    239244 * @param page Virtual page.
    240245 *
    241246 * @return NULL if there is no such mapping; requested mapping otherwise.
     247 *
    242248 */
    243249pte_t *ht_mapping_find(as_t *as, uintptr_t page)
    244250{
    245         link_t *hlp;
    246         pte_t *t = NULL;
    247251        unative_t key[2] = {
    248252                (uintptr_t) as,
    249253                page = ALIGN_DOWN(page, PAGE_SIZE)
    250254        };
    251        
    252         hlp = hash_table_find(&page_ht, key);
    253         if (hlp)
    254                 t = hash_table_get_instance(hlp, pte_t, link);
    255 
    256         return t;
     255
     256        ASSERT(interrupts_disabled());
     257        ASSERT(page_table_locked(as));
     258       
     259        link_t *cur = hash_table_find(&page_ht, key);
     260        if (cur)
     261                return hash_table_get_instance(cur, pte_t, link);
     262       
     263        return NULL;
    257264}
    258265
Note: See TracChangeset for help on using the changeset viewer.