Subversion Repositories HelenOS

Rev

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

Rev 2089 Rev 2094
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 *new)
866
void as_switch(as_t *old, as_t *replace)
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();
Line 898... Line 898...
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(&new->lock);
903
    mutex_lock_active(&replace->lock);
904
    if ((new->cpu_refcount++ == 0) && (new != AS_KERNEL)) {
904
    if ((replace->cpu_refcount++ == 0) && (replace != AS_KERNEL)) {
905
        if (new->asid != ASID_INVALID) {
905
        if (replace->asid != ASID_INVALID) {
906
            list_remove(&new->inactive_as_with_asid_link);
906
            list_remove(&replace->inactive_as_with_asid_link);
907
        } else {
907
        } else {
908
            /*
908
            /*
909
             * Defer call to asid_get() until new->lock is released.
909
             * Defer call to asid_get() until replace->lock is released.
910
             */
910
             */
911
            needs_asid = true;
911
            needs_asid = true;
912
        }
912
        }
913
    }
913
    }
914
    SET_PTL0_ADDRESS(new->page_table);
914
    SET_PTL0_ADDRESS(replace->page_table);
915
    mutex_unlock(&new->lock);
915
    mutex_unlock(&replace->lock);
916
 
916
 
917
    if (needs_asid) {
917
    if (needs_asid) {
918
        /*
918
        /*
919
         * Allocation of new ASID was deferred
919
         * Allocation of new ASID was deferred
920
         * until now in order to avoid deadlock.
920
         * until now in order to avoid deadlock.
921
         */
921
         */
922
        asid_t asid;
922
        asid_t asid;
923
       
923
       
924
        asid = asid_get();
924
        asid = asid_get();
925
        mutex_lock_active(&new->lock);
925
        mutex_lock_active(&replace->lock);
926
        new->asid = asid;
926
        replace->asid = asid;
927
        mutex_unlock(&new->lock);
927
        mutex_unlock(&replace->lock);
928
    }
928
    }
929
    spinlock_unlock(&inactive_as_with_asid_lock);
929
    spinlock_unlock(&inactive_as_with_asid_lock);
930
    interrupts_restore(ipl);
930
    interrupts_restore(ipl);
931
   
931
   
932
    /*
932
    /*
933
     * Perform architecture-specific steps.
933
     * Perform architecture-specific steps.
934
     * (e.g. write ASID to hardware register etc.)
934
     * (e.g. write ASID to hardware register etc.)
935
     */
935
     */
936
    as_install_arch(new);
936
    as_install_arch(replace);
937
   
937
   
938
    AS = new;
938
    AS = replace;
939
}
939
}
940
 
940
 
941
/** Convert address space area flags to page flags.
941
/** Convert address space area flags to page flags.
942
 *
942
 *
943
 * @param aflags Flags of some address space area.
943
 * @param aflags Flags of some address space area.