Subversion Repositories HelenOS

Rev

Rev 3386 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3386 Rev 4153
Line 120... Line 120...
120
{
120
{
121
    as_t *as = (as_t *) obj;
121
    as_t *as = (as_t *) obj;
122
    int rc;
122
    int rc;
123
 
123
 
124
    link_initialize(&as->inactive_as_with_asid_link);
124
    link_initialize(&as->inactive_as_with_asid_link);
125
    mutex_initialize(&as->lock, MUTEX_PASSIVE);
125
    mutex_initialize(&as->lock, MUTEX_PASSIVE);
126
   
126
   
127
    rc = as_constructor_arch(as, flags);
127
    rc = as_constructor_arch(as, flags);
128
   
128
   
129
    return rc;
129
    return rc;
130
}
130
}
Line 144... Line 144...
144
    as_slab = slab_cache_create("as_slab", sizeof(as_t), 0,
144
    as_slab = slab_cache_create("as_slab", sizeof(as_t), 0,
145
        as_constructor, as_destructor, SLAB_CACHE_MAGDEFERRED);
145
        as_constructor, as_destructor, SLAB_CACHE_MAGDEFERRED);
146
   
146
   
147
    AS_KERNEL = as_create(FLAG_AS_KERNEL);
147
    AS_KERNEL = as_create(FLAG_AS_KERNEL);
148
    if (!AS_KERNEL)
148
    if (!AS_KERNEL)
149
        panic("can't create kernel address space\n");
149
        panic("Cannot create kernel address space.");
150
   
150
   
-
 
151
    /* Make sure the kernel address space
-
 
152
     * reference count never drops to zero.
-
 
153
     */
-
 
154
    atomic_set(&AS_KERNEL->refcount, 1);
151
}
155
}
152
 
156
 
153
/** Create address space.
157
/** Create address space.
154
 *
158
 *
155
 * @param flags     Flags that influence the way in wich the address space
159
 * @param flags     Flags that influence the way in wich the address space
Line 174... Line 178...
174
#ifdef AS_PAGE_TABLE
178
#ifdef AS_PAGE_TABLE
175
    as->genarch.page_table = page_table_create(flags);
179
    as->genarch.page_table = page_table_create(flags);
176
#else
180
#else
177
    page_table_create(flags);
181
    page_table_create(flags);
178
#endif
182
#endif
179
 
183
   
180
    return as;
184
    return as;
181
}
185
}
182
 
186
 
183
/** Destroy adress space.
187
/** Destroy adress space.
184
 *
188
 *
Line 383... Line 387...
383
        return EPERM;
387
        return EPERM;
384
    }
388
    }
385
   
389
   
386
    if (pages < area->pages) {
390
    if (pages < area->pages) {
387
        bool cond;
391
        bool cond;
388
        uintptr_t start_free = area->base + pages*PAGE_SIZE;
392
        uintptr_t start_free = area->base + pages * PAGE_SIZE;
389
 
393
 
390
        /*
394
        /*
391
         * Shrinking the area.
395
         * Shrinking the area.
392
         * No need to check for overlaps.
396
         * No need to check for overlaps.
393
         */
397
         */
394
 
398
 
395
        /*
399
        /*
396
         * Start TLB shootdown sequence.
400
         * Start TLB shootdown sequence.
397
         */
401
         */
398
        tlb_shootdown_start(TLB_INVL_PAGES, AS->asid, area->base +
402
        tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base +
399
            pages * PAGE_SIZE, area->pages - pages);
403
            pages * PAGE_SIZE, area->pages - pages);
400
 
404
 
401
        /*
405
        /*
402
         * Remove frames belonging to used space starting from
406
         * Remove frames belonging to used space starting from
403
         * the highest addresses downwards until an overlap with
407
         * the highest addresses downwards until an overlap with
Line 438... Line 442...
438
       
442
       
439
                    cond = false;   /* we are almost done */
443
                    cond = false;   /* we are almost done */
440
                    i = (start_free - b) >> PAGE_WIDTH;
444
                    i = (start_free - b) >> PAGE_WIDTH;
441
                    if (!used_space_remove(area, start_free,
445
                    if (!used_space_remove(area, start_free,
442
                        c - i))
446
                        c - i))
443
                        panic("Could not remove used "
447
                        panic("Cannot remove used "
444
                            "space.\n");
448
                            "space.");
445
                } else {
449
                } else {
446
                    /*
450
                    /*
447
                     * The interval of used space can be
451
                     * The interval of used space can be
448
                     * completely removed.
452
                     * completely removed.
449
                     */
453
                     */
450
                    if (!used_space_remove(area, b, c))
454
                    if (!used_space_remove(area, b, c))
451
                        panic("Could not remove used "
455
                        panic("Cannot remove used "
452
                            "space.\n");
456
                            "space.");
453
                }
457
                }
454
           
458
           
455
                for (; i < c; i++) {
459
                for (; i < c; i++) {
456
                    pte_t *pte;
460
                    pte_t *pte;
457
           
461
           
Line 767... Line 771...
767
 * The idea is to have the same data, but with a different access mode.
771
 * The idea is to have the same data, but with a different access mode.
768
 * This is needed e.g. for writing code into memory and then executing it.
772
 * This is needed e.g. for writing code into memory and then executing it.
769
 * In order for this to work properly, this may copy the data
773
 * In order for this to work properly, this may copy the data
770
 * into private anonymous memory (unless it's already there).
774
 * into private anonymous memory (unless it's already there).
771
 *
775
 *
772
 * @param as        Address space.
776
 * @param as      Address space.
773
 * @param flags     Flags of the area memory.
777
 * @param flags   Flags of the area memory.
774
 * @param address   Address withing the area to be changed.
778
 * @param address Address within the area to be changed.
-
 
779
 *
-
 
780
 * @return Zero on success or a value from @ref errno.h on failure.
775
 *
781
 *
776
 * @return      Zero on success or a value from @ref errno.h on failure.
-
 
777
 */
782
 */
778
int as_area_change_flags(as_t *as, int flags, uintptr_t address)
783
int as_area_change_flags(as_t *as, int flags, uintptr_t address)
779
{
784
{
780
    as_area_t *area;
785
    as_area_t *area;
781
    uintptr_t base;
786
    uintptr_t base;
Line 783... Line 788...
783
    ipl_t ipl;
788
    ipl_t ipl;
784
    int page_flags;
789
    int page_flags;
785
    uintptr_t *old_frame;
790
    uintptr_t *old_frame;
786
    index_t frame_idx;
791
    index_t frame_idx;
787
    count_t used_pages;
792
    count_t used_pages;
788
 
793
   
789
    /* Flags for the new memory mapping */
794
    /* Flags for the new memory mapping */
790
    page_flags = area_flags_to_page_flags(flags);
795
    page_flags = area_flags_to_page_flags(flags);
791
 
796
 
792
    ipl = interrupts_disable();
797
    ipl = interrupts_disable();
793
    mutex_lock(&as->lock);
798
    mutex_lock(&as->lock);
Line 797... Line 802...
797
        mutex_unlock(&as->lock);
802
        mutex_unlock(&as->lock);
798
        interrupts_restore(ipl);
803
        interrupts_restore(ipl);
799
        return ENOENT;
804
        return ENOENT;
800
    }
805
    }
801
 
806
 
802
    if (area->sh_info || area->backend != &anon_backend) {
807
    if ((area->sh_info) || (area->backend != &anon_backend)) {
803
        /* Copying shared areas not supported yet */
808
        /* Copying shared areas not supported yet */
804
        /* Copying non-anonymous memory not supported yet */
809
        /* Copying non-anonymous memory not supported yet */
805
        mutex_unlock(&area->lock);
810
        mutex_unlock(&area->lock);
806
        mutex_unlock(&as->lock);
811
        mutex_unlock(&as->lock);
807
        interrupts_restore(ipl);
812
        interrupts_restore(ipl);
Line 868... Line 873...
868
    /*
873
    /*
869
     * Finish TLB shootdown sequence.
874
     * Finish TLB shootdown sequence.
870
     */
875
     */
871
 
876
 
872
    tlb_invalidate_pages(as->asid, area->base, area->pages);
877
    tlb_invalidate_pages(as->asid, area->base, area->pages);
-
 
878
   
873
    /*
879
    /*
874
     * Invalidate potential software translation caches (e.g. TSB on
880
     * Invalidate potential software translation caches (e.g. TSB on
875
     * sparc64).
881
     * sparc64).
876
     */
882
     */
877
    as_invalidate_translation_cache(as, area->base, area->pages);
883
    as_invalidate_translation_cache(as, area->base, area->pages);
Line 1658... Line 1664...
1658
            }
1664
            }
1659
        }
1665
        }
1660
    }
1666
    }
1661
 
1667
 
1662
    panic("Inconsistency detected while adding %" PRIc " pages of used "
1668
    panic("Inconsistency detected while adding %" PRIc " pages of used "
1663
        "space at %p.\n", count, page);
1669
        "space at %p.", count, page);
1664
}
1670
}
1665
 
1671
 
1666
/** Mark portion of address space area as unused.
1672
/** Mark portion of address space area as unused.
1667
 *
1673
 *
1668
 * The address space area must be already locked.
1674
 * The address space area must be already locked.
Line 1837... Line 1843...
1837
        }
1843
        }
1838
    }
1844
    }
1839
 
1845
 
1840
error:
1846
error:
1841
    panic("Inconsistency detected while removing %" PRIc " pages of used "
1847
    panic("Inconsistency detected while removing %" PRIc " pages of used "
1842
        "space from %p.\n", count, page);
1848
        "space from %p.", count, page);
1843
}
1849
}
1844
 
1850
 
1845
/** Remove reference to address space area share info.
1851
/** Remove reference to address space area share info.
1846
 *
1852
 *
1847
 * If the reference count drops to 0, the sh_info is deallocated.
1853
 * If the reference count drops to 0, the sh_info is deallocated.