os-irix6.2.tcl 7.1 KB
#
# Copyright (C) 1996-1998 by the Board of Trustees
#    of Leland Stanford Junior University.
# 
# This file is part of the SimOS distribution. 
# See LICENSE file for terms of the license. 
#

###
### This file is responsible for raising OS level annotations and tracking
### the current process.
###
###

####
#### init this module
####

annotation type osEvent enum {
        startUser   endUser
        startKernel endKernel
        startIdle   endIdle
        startSync   endSync
        switchIn    switchOut
        procstart   procexit   procexec
}

if [info exists R4000_KERNEL] {
    proc inUserMode {} {
        global sr
        expr !($sr & 0x4) && !($sr &0x2) && (($sr & 0x18) == 0x10)
    }

} else {
    proc inUserMode {} {
        global sr
        expr ($sr & 0x02) != 0
    }
}


####
#### the annotations 
####

##
## process and idle tracking
##

annotation set simos enter {
    set PID($CPU) -1
    set PROCESS($CPU) ""
    if {0} {
    # We'll have to fix this later to restore checkpoints
    if [catch {symbol read kernel::$private.p_curproc}] {
        # booting
        set PROCESS($CPU) "boot"
        set PID($CPU) boot$CPU
    } elseif {(([hex $pc] >= [symbol read kernel::idle:START])
               && ([hex $pc] <= ([symbol read kernel::idle:END] + 4)))
              || ((![catch {symbol read kernel::checkRunq:START}]) && 
                  ([hex $pc] >= [symbol read kernel::checkRunq:START])
                  && ([hex $pc] <= ([symbol read kernel::checkRunq:END] 
                                    + 4)))} {
        set PROCESS($CPU) "idle"
        set PID($CPU) idle$CPU
    } elseif {[symbol read kernel::$u.u_procp->p_sonproc] == $MCPU($CPU)} {
        set PROCESS($CPU) [symbol read kernel::$u.u_comm]
        set PID($CPU) [symbol read kernel::$u.u_procp->p_epid]    
    } else {
        set PROCESS($CPU) "runq"
        set PID($CPU) "runq$CPU"
    }
    }
}

proc newproc {pid process} {
    global CPU PROCESS PID
    annotation exec osEvent switchOut
    log "newproc old ($PID($CPU),$PROCESS($CPU)) new ($pid, $process)\n"
    set PROCESS($CPU) $process
    set PID($CPU) $pid
    annotation exec osEvent switchIn
}

annotation set pc kernel::idle:START {
    newproc idle$CPU "idle"
    annotation exec osEvent startIdle
}

annotation set pc kernel::idle:END {
    if {$PROCESS($CPU) != "idle"} {
        # this can happen when we take an interrupt on idle end
        console "OS.TCL: ignoring end idle when process != idle $CYCLES\n"
    } else {
        annotation exec osEvent endIdle
        newproc runq$CPU "runq"
    }
}

annotation set pc kernel::swtch:START {
    log "swtch:  "
    newproc runq$CPU "runq"
}

annotation set pc kernel::swtch:END {
    log "switch end:  "
    newproc [symbol read kernel::$u.u_procp->p_epid] [symbol read kernel::$u.u_comm]
}

annotation set pc kernel::pswtch:START {
    annotation exec osEvent procexit
    log "pswtch:  "
    newproc runq$CPU "runq"
}

annotation set pc kernel:fork.c:procdup:END {
    set pid [symbol read kernel::$u.u_procp->p_epid]
    if {$pid != $PID($CPU)} {
        # child process of the fork
        console "procdup\n"
        newproc $pid [symbol read kernel::$u.u_comm]
        annotation exec osEvent procstart
    }
}

annotation set pc kernel::exece:END {
    annotation exec osEvent switchOut
    set PROCESS($CPU) [symbol read kernel::$u.u_comm]
    console "OS.TCL:setting process on exece to $PROCESS($CPU)\n"
    annotation exec osEvent procexec
    annotation exec osEvent switchIn
}

annotation set pc kernel::resume:END {
    log "resume_end:  "
    newproc [symbol read kernel::$u.u_procp->p_epid] [symbol read kernel::$u.u_comm]
}

annotation set pc kernel::swtch:ann_swtch_resume_same {
    log "swtch_resume_same:  "
    newproc [symbol read kernel::$u.u_procp->p_epid] [symbol read kernel::$u.u_comm]
}

annotation set pc kernel::resumekthread:END {
    log "resumekthread:  "
    set curthread "(*(struct kthread*)[symbol read kernel::$private.p_curproc])"
    newproc [symbol read kernel::$curthread.k_pid] [symbol read kernel::$curthread.k_name]
}

if {$detailLevel >= 2} {
    ##
    ## kernel - user transitions
    ##

    set MAX_CPUS 256

    for {set i 0} {$i < $MAX_CPUS} {incr i} {
        set utlb($i) 0
    }
    
    annotation set utlb {
        set utlb($CPU) 1
        if {!($epc & $K0BASE)} {
            annotation exec osEvent endUser
        }
        annotation exec osEvent startKernel
    }
    
    annotation set exc {
        if {!$utlb($CPU)} {
            if {!($epc & $K0BASE)} {
                annotation exec osEvent endUser
            }
            annotation exec osEvent startKernel
        }
        set utlb($CPU) 0
    }
        
    annotation set inst rfe {
        set utlb($CPU) 0
        annotation exec osEvent endKernel
        if [inUserMode] {
            annotation exec osEvent startUser
        }
    }
        

    ##
    ## synchronization stuff
    ##

    if ![catch {symbol read kernel::netisr_init} msg] {

        # MP kernel
        log "INFO: IRIX is multiprocessor\n"
            
        annotation set pc kernel::io_splock:START {
            annotation exec osEvent startSync
        }
            
        if [catch {symbol read kernel::io_splock:ann_splock_gotit}] {
            annotation set pc kernel::io_splock:END {
                annotation exec osEvent endSync
            }
        } else {
            annotation set pc kernel::io_splock:ann_splock_gotit {
                annotation exec osEvent endSync
            }
        }
        
        annotation set pc kernel::spsemahi:START {
            annotation exec osEvent startSync
        }
        
        annotation set pc kernel::spsemahi:ann_spsemahi_gotit {
            annotation exec osEvent endSync
        }
        
        annotation set pc kernel::svsema:START {
            annotation exec osEvent startSync
        }
        
        annotation set pc kernel::svsema:END {
            annotation exec osEvent endSync
        }
        
        annotation set pc kernel::svsemax:START {
            annotation exec osEvent startSync
        }
        
        annotation set pc kernel::svsemax:END {
            annotation exec osEvent endSync
        }
        
        annotation set pc kernel::io_splockspl:START {
            annotation exec osEvent startSync
        }
        
        annotation set pc kernel::io_splockspl:ann_splockspl_gotit {
            annotation exec osEvent endSync
        }
        
        annotation set pc kernel::io_spunlockspl:START {
            annotation exec osEvent startSync
        }
        
        annotation set pc kernel::io_spunlockspl:END {
            annotation exec osEvent endSync
        }
        
        annotation set pc kernel::_trylock:START {
            annotation exec osEvent startSync
        }
        
        annotation set pc kernel::_trylock:ann_trylock_gotit {
            annotation exec osEvent endSync
        }
        
        annotation set pc kernel::spsema:START {
            annotation exec osEvent startSync
        }
        
        annotation set pc kernel::spsema:END {
            annotation exec osEvent endSync
        }
    } else {
        log "INFO: IRIX is uniprocessor\n"
    }
}