Subversion Repositories HelenOS

Rev

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

Rev 2094 Rev 2106
Line 166... Line 166...
166
        as->asid = ASID_INVALID;
166
        as->asid = ASID_INVALID;
167
   
167
   
168
    as->refcount = 0;
168
    as->refcount = 0;
169
    as->cpu_refcount = 0;
169
    as->cpu_refcount = 0;
170
#ifdef AS_PAGE_TABLE
170
#ifdef AS_PAGE_TABLE
171
    as->page_table = page_table_create(flags);
171
    as->genarch.page_table = page_table_create(flags);
172
#else
172
#else
173
    page_table_create(flags);
173
    page_table_create(flags);
174
#endif
174
#endif
175
 
175
 
176
    return as;
176
    return as;
Line 218... Line 218...
218
        }
218
        }
219
    }
219
    }
220
 
220
 
221
    btree_destroy(&as->as_area_btree);
221
    btree_destroy(&as->as_area_btree);
222
#ifdef AS_PAGE_TABLE
222
#ifdef AS_PAGE_TABLE
223
    page_table_destroy(as->page_table);
223
    page_table_destroy(as->genarch.page_table);
224
#else
224
#else
225
    page_table_destroy(NULL);
225
    page_table_destroy(NULL);
226
#endif
226
#endif
227
 
227
 
228
    interrupts_restore(ipl);
228
    interrupts_restore(ipl);
Line 861... Line 861...
861
 * scheduling. Sleeping here would lead to deadlock on wakeup.
861
 * scheduling. Sleeping here would lead to deadlock on wakeup.
862
 *
862
 *
863
 * @param old Old address space or NULL.
863
 * @param old Old address space or NULL.
864
 * @param new New address space.
864
 * @param new New address space.
865
 */
865
 */
866
void as_switch(as_t *old, as_t *replace)
866
void as_switch(as_t *old_as, as_t *new_as)
867
{
867
{
868
    ipl_t ipl;
868
    ipl_t ipl;
869
    bool needs_asid = false;
869
    bool needs_asid = false;
870
   
870
   
871
    ipl = interrupts_disable();
871
    ipl = interrupts_disable();
872
    spinlock_lock(&inactive_as_with_asid_lock);
872
    spinlock_lock(&inactive_as_with_asid_lock);
873
 
873
 
874
    /*
874
    /*
875
     * First, take care of the old address space.
875
     * First, take care of the old address space.
876
     */
876
     */
877
    if (old) {
877
    if (old_as) {
878
        mutex_lock_active(&old->lock);
878
        mutex_lock_active(&old_as->lock);
879
        ASSERT(old->cpu_refcount);
879
        ASSERT(old_as->cpu_refcount);
880
        if((--old->cpu_refcount == 0) && (old != AS_KERNEL)) {
880
        if((--old_as->cpu_refcount == 0) && (old_as != AS_KERNEL)) {
881
            /*
881
            /*
882
             * The old address space is no longer active on
882
             * The old address space is no longer active on
883
             * any processor. It can be appended to the
883
             * any processor. It can be appended to the
884
             * list of inactive address spaces with assigned
884
             * list of inactive address spaces with assigned
885
             * ASID.
885
             * ASID.
886
             */
886
             */
887
             ASSERT(old->asid != ASID_INVALID);
887
             ASSERT(old_as->asid != ASID_INVALID);
888
             list_append(&old->inactive_as_with_asid_link,
888
             list_append(&old_as->inactive_as_with_asid_link,
889
                 &inactive_as_with_asid_head);
889
                 &inactive_as_with_asid_head);
890
        }
890
        }
891
        mutex_unlock(&old->lock);
891
        mutex_unlock(&old_as->lock);
892
 
892
 
893
        /*
893
        /*
894
         * Perform architecture-specific tasks when the address space
894
         * Perform architecture-specific tasks when the address space
895
         * is being removed from the CPU.
895
         * is being removed from the CPU.
896
         */
896
         */
897
        as_deinstall_arch(old);
897
        as_deinstall_arch(old_as);
898
    }
898
    }
899
 
899
 
900
    /*
900
    /*
901
     * Second, prepare the new address space.
901
     * Second, prepare the new address space.
902
     */
902
     */
903
    mutex_lock_active(&replace->lock);
903
    mutex_lock_active(&new_as->lock);
904
    if ((replace->cpu_refcount++ == 0) && (replace != AS_KERNEL)) {
904
    if ((new_as->cpu_refcount++ == 0) && (new_as != AS_KERNEL)) {
905
        if (replace->asid != ASID_INVALID) {
905
        if (new_as->asid != ASID_INVALID) {
906
            list_remove(&replace->inactive_as_with_asid_link);
906
            list_remove(&new_as->inactive_as_with_asid_link);
907
        } else {
907
        } else {
908
            /*
908
            /*
909
             * Defer call to asid_get() until replace->lock is released.
909
             * Defer call to asid_get() until new_as->lock is released.
910
             */
910
             */
911
            needs_asid = true;
911
            needs_asid = true;
912
        }
912
        }
913
    }
913
    }
-
 
914
#ifdef AS_PAGE_TABLE
914
    SET_PTL0_ADDRESS(replace->page_table);
915
    SET_PTL0_ADDRESS(new_as->genarch.page_table);
-
 
916
#endif
915
    mutex_unlock(&replace->lock);
917
    mutex_unlock(&new_as->lock);
916
 
918
 
917
    if (needs_asid) {
919
    if (needs_asid) {
918
        /*
920
        /*
919
         * Allocation of new ASID was deferred
921
         * Allocation of new ASID was deferred
920
         * until now in order to avoid deadlock.
922
         * until now in order to avoid deadlock.
921
         */
923
         */
922
        asid_t asid;
924
        asid_t asid;
923
       
925
       
924
        asid = asid_get();
926
        asid = asid_get();
925
        mutex_lock_active(&replace->lock);
927
        mutex_lock_active(&new_as->lock);
926
        replace->asid = asid;
928
        new_as->asid = asid;
927
        mutex_unlock(&replace->lock);
929
        mutex_unlock(&new_as->lock);
928
    }
930
    }
929
    spinlock_unlock(&inactive_as_with_asid_lock);
931
    spinlock_unlock(&inactive_as_with_asid_lock);
930
    interrupts_restore(ipl);
932
    interrupts_restore(ipl);
931
   
933
   
932
    /*
934
    /*
933
     * Perform architecture-specific steps.
935
     * Perform architecture-specific steps.
934
     * (e.g. write ASID to hardware register etc.)
936
     * (e.g. write ASID to hardware register etc.)
935
     */
937
     */
936
    as_install_arch(replace);
938
    as_install_arch(new_as);
937
   
939
   
938
    AS = replace;
940
    AS = new_as;
939
}
941
}
940
 
942
 
941
/** Convert address space area flags to page flags.
943
/** Convert address space area flags to page flags.
942
 *
944
 *
943
 * @param aflags Flags of some address space area.
945
 * @param aflags Flags of some address space area.