Changeset 6a3c9a7 in mainline


Ignore:
Timestamp:
2006-01-30T23:44:00Z (19 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
fc1e4f6
Parents:
a60c748
Message:

Remove address space area mapping array.
The information is to be stored directly in page tables.
This is to better support 64-bit systems which can have
fairly large address space areas.

Location:
generic
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • generic/include/mm/as.h

    ra60c748 r6a3c9a7  
    6666        size_t size;            /**< Size of this area in multiples of PAGE_SIZE. */
    6767        __address base;         /**< Base address of this area. */
    68         index_t *mapping;       /**< Map of physical frame numbers mapped to virtual page numbers in this area. */
    6968};
    7069
     
    7776 */
    7877struct as {
    79         /** Protected by asidlock. Must be acquired before as-> lock. */
     78        /** Protected by asidlock. Must be acquired before as->lock. */
    8079        link_t as_with_asid_link;
    8180
     
    8887extern as_t * as_create(pte_t *ptl0, int flags);
    8988extern as_area_t *as_area_create(as_t *as, as_area_type_t type, size_t size, __address base);
    90 extern void as_area_set_mapping(as_area_t *a, index_t vpn, index_t pfn);
     89extern void as_set_mapping(as_t *as, __address page, __address frame);
    9190extern int as_page_fault(__address page);
    9291extern void as_install(as_t *m);
  • generic/src/main/kinit.c

    ra60c748 r6a3c9a7  
    7272        as_t *as;
    7373        as_area_t *a;
    74         index_t frame, frames;
    75         index_t pfn;
     74        __address frame;
     75        count_t frames;
     76        int i;
    7677        task_t *u;
    7778
     
    161162                 */
    162163               
    163                 frame = KA2PA(config.init_addr) / FRAME_SIZE;
     164                frame = KA2PA(config.init_addr);
    164165                frames = config.init_size / FRAME_SIZE;
    165166                if (config.init_size % FRAME_SIZE > 0)
     
    170171                        panic("as_area_create: text\n");
    171172               
    172                 for (pfn = 0; pfn < frames; pfn++)
    173                         as_area_set_mapping(a, pfn, frame + pfn);
    174        
    175173                /*
    176174                 * Create the data as_area.
     
    179177                if (!a)
    180178                        panic("as_area_create: stack\n");
     179
     180                /*
     181                 * Initialize text area mapping.
     182                 */
     183                for (i = 0; i < frames; i++)
     184                        as_set_mapping(as, UTEXT_ADDRESS + i * PAGE_SIZE, frame + i * FRAME_SIZE);
     185
    181186       
    182187                thread_ready(t);
  • generic/src/mm/as.c

    ra60c748 r6a3c9a7  
    6060#define KAS_INDICES             (1+(KAS_END_INDEX-KAS_START_INDEX))
    6161
    62 /*
    63  * Here we assume that PFN (Physical Frame Number) space
    64  * is smaller than the width of index_t. UNALLOCATED_PFN
    65  * can be then used to mark mappings wich were not
    66  * yet allocated a physical frame.
    67  */
    68 #define UNALLOCATED_PFN         ((index_t) -1)
     62static int get_area_flags(as_area_t *a);
    6963
    7064/** Create address space. */
     
    134128       
    135129        a = (as_area_t *) malloc(sizeof(as_area_t));
    136         if (a) {
    137                 int i;
    138        
    139                 a->mapping = (index_t *) malloc(size * sizeof(index_t));
    140                 if (!a->mapping) {
    141                         free(a);
    142                         spinlock_unlock(&as->lock);
    143                         interrupts_restore(ipl);
    144                         return NULL;
    145                 }
    146                
    147                 for (i=0; i<size; i++) {
    148                         /*
    149                          * Frames will be allocated on-demand by
    150                          * as_page_fault() or preloaded by
    151                          * as_area_set_mapping().
    152                          */
    153                         a->mapping[i] = UNALLOCATED_PFN;
    154                 }
    155                
     130        if (a) {       
    156131                spinlock_initialize(&a->lock, "as_area_lock");
    157132                       
     
    162137               
    163138                list_append(&a->link, &as->as_area_head);
    164 
    165139        }
    166140
     
    171145}
    172146
    173 /** Load mapping for address space area.
    174  *
    175  * Initialize a->mapping.
    176  *
    177  * @param a   Target address space area.
    178  * @param vpn Page number relative to area start.
    179  * @param pfn Frame number to map.
    180  */
    181 void as_area_set_mapping(as_area_t *a, index_t vpn, index_t pfn)
    182 {
    183         ASSERT(vpn < a->size);
    184         ASSERT(a->mapping[vpn] == UNALLOCATED_PFN);
    185         ASSERT(pfn != UNALLOCATED_PFN);
    186        
     147/** Initialize mapping for one page of address space.
     148 *
     149 * This functions maps 'page' to 'frame' according
     150 * to attributes of the address space area to
     151 * wich 'page' belongs.
     152 *
     153 * @param a Target address space.
     154 * @param page Virtual page within the area.
     155 * @param frame Physical frame to which page will be mapped.
     156 */
     157void as_set_mapping(as_t *as, __address page, __address frame)
     158{
     159        as_area_t *a, *area = NULL;
     160        link_t *cur;
    187161        ipl_t ipl;
    188162       
    189163        ipl = interrupts_disable();
    190         spinlock_lock(&a->lock);
    191        
    192         a->mapping[vpn] = pfn;
    193        
    194         spinlock_unlock(&a->lock);
     164        spinlock_lock(&as->lock);
     165       
     166        /*
     167         * First, try locate an area.
     168         */
     169        for (cur = as->as_area_head.next; cur != &as->as_area_head; cur = cur->next) {
     170                a = list_get_instance(cur, as_area_t, link);
     171                spinlock_lock(&a->lock);
     172
     173                if ((page >= a->base) && (page < a->base + a->size * PAGE_SIZE)) {
     174                        area = a;
     175                        break;
     176                }
     177               
     178                spinlock_unlock(&a->lock);
     179        }
     180       
     181        if (!area) {
     182                panic("page not part of any as_area\n");
     183        }
     184
     185        /*
     186         * Note: area->lock is held.
     187         */
     188       
     189        page_mapping_insert(page, as->asid, frame, get_area_flags(area), (__address) as->ptl0);
     190       
     191        spinlock_unlock(&area->lock);
     192        spinlock_unlock(&as->lock);
    195193        interrupts_restore(ipl);
    196194}
     
    207205int as_page_fault(__address page)
    208206{
    209         int flags;
    210207        link_t *cur;
    211208        as_area_t *a, *area = NULL;
    212         index_t vpn;
    213209        __address frame;
    214210       
     
    229225                         * TODO: access checking
    230226                         */
    231                        
    232                         vpn = (page - a->base) / PAGE_SIZE;
    233227                        area = a;
    234228                        break;
     
    252246       
    253247        /*
    254          * Decide if a frame needs to be allocated.
    255          * If so, allocate it and adjust area->mapping map.
    256          */
    257         if (area->mapping[vpn] == UNALLOCATED_PFN) {
    258                 frame = frame_alloc(0, ONE_FRAME, NULL);
    259                 memsetb(PA2KA(frame), FRAME_SIZE, 0);
    260                 area->mapping[vpn] = frame / FRAME_SIZE;
    261                 ASSERT(area->mapping[vpn] != UNALLOCATED_PFN);
    262         } else
    263                 frame = area->mapping[vpn] * FRAME_SIZE;
    264        
    265         switch (area->type) {
     248         * In general, there can be several reasons that
     249         * can have caused this fault.
     250         *
     251         * - non-existent mapping: the area is a scratch
     252         *   area (e.g. stack) and so far has not been
     253         *   allocated a frame for the faulting page
     254         *
     255         * - non-present mapping: another possibility,
     256         *   currently not implemented, would be frame
     257         *   reuse; when this becomes a possibility,
     258         *   do not forget to distinguish between
     259         *   the different causes
     260         */
     261        frame = frame_alloc(0, ONE_FRAME, NULL);
     262        memsetb(PA2KA(frame), FRAME_SIZE, 0);
     263       
     264        /*
     265         * Map 'page' to 'frame'.
     266         * Note that TLB shootdown is not attempted as only new information is being
     267         * inserted into page tables.
     268         */
     269        page_mapping_insert(page, AS->asid, frame, get_area_flags(area), (__address) AS->ptl0);
     270       
     271        spinlock_unlock(&area->lock);
     272        spinlock_unlock(&AS->lock);
     273
     274        return 1;
     275}
     276
     277/** Install address space on CPU.
     278 *
     279 * @param as Address space.
     280 */
     281void as_install(as_t *as)
     282{
     283        ipl_t ipl;
     284       
     285        asid_install(as);
     286       
     287        ipl = interrupts_disable();
     288        spinlock_lock(&as->lock);
     289        ASSERT(as->ptl0);
     290        SET_PTL0_ADDRESS(as->ptl0);
     291        spinlock_unlock(&as->lock);
     292        interrupts_restore(ipl);
     293
     294        /*
     295         * Perform architecture-specific steps.
     296         * (e.g. write ASID to hardware register etc.)
     297         */
     298        as_install_arch(as);
     299       
     300        AS = as;
     301}
     302
     303/** Compute flags for virtual address translation subsytem.
     304 *
     305 * The address space area must be locked.
     306 * Interrupts must be disabled.
     307 *
     308 * @param a Address space area.
     309 *
     310 * @return Flags to be used in page_mapping_insert().
     311 */
     312int get_area_flags(as_area_t *a)
     313{
     314        int flags;
     315
     316        switch (a->type) {
    266317                case AS_AREA_TEXT:
    267318                        flags = PAGE_EXEC | PAGE_READ | PAGE_USER | PAGE_PRESENT | PAGE_CACHEABLE;
     
    272323                        break;
    273324                default:
    274                         panic("unexpected as_area_type_t %d", area->type);
    275         }
    276 
    277         /*
    278          * Map 'page' to 'frame'.
    279          * Note that TLB shootdown is not attempted as only new information is being
    280          * inserted into page tables.
    281          */
    282         page_mapping_insert(page, AS->asid, frame, flags, (__address) AS->ptl0);
    283        
    284         spinlock_unlock(&area->lock);
    285         spinlock_unlock(&AS->lock);
    286 
    287         return 1;
    288 }
    289 
    290 /** Install address space on CPU.
    291  *
    292  * @param as Address space.
    293  */
    294 void as_install(as_t *as)
    295 {
    296         ipl_t ipl;
    297        
    298         asid_install(as);
    299        
    300         ipl = interrupts_disable();
    301         spinlock_lock(&as->lock);
    302         ASSERT(as->ptl0);
    303         SET_PTL0_ADDRESS(as->ptl0);
    304         spinlock_unlock(&as->lock);
    305         interrupts_restore(ipl);
    306 
    307         /*
    308          * Perform architecture-specific steps.
    309          * (e.g. write ASID to hardware register etc.)
    310          */
    311         as_install_arch(as);
    312        
    313         AS = as;
    314 }
     325                        panic("unexpected as_area_type_t %d", a->type);
     326        }
     327       
     328        return flags;
     329}
Note: See TracChangeset for help on using the changeset viewer.