os.tcl
10.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
#
# Copyright (C) 1998 by the Board of Trustees
# of Leland Stanford Junior University.
# Copyright (C) 1998 Digital Equipment Corporation
#
# This file is part of the SimOS distribution.
# See LICENSE file for terms of the license.
#
#
# 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
####
FileSourced osf/os.tcl
source syscalls.tcl
source osfpal.tcl
annotation type osEvent enum {
startUser endUser
startKernel endKernel
startPal endPal
startIdle endIdle
startSync endSync
switchIn switchOut
procstart procexit procexec procwait
}
# must agree with cpus-alpha/alpha-shared/ev5.c
annotation type exc enum {
reset mchk arith interrupt ndtb_miss pdtb_miss unalign dtb_fault itb_miss itb_acv opdec fen pal
}
proc inUserMode {} {
global IPR
set IPR_PS 0x10f
set PS $IPR(0x10f)
return [expr ($PS & 24) != 0]
}
####
#### the annotations
####
##
## process and idle tracking
##
annotation set simos enter {
set palCodeCount($CPU) 0
set PCBB($CPU) $IPR(0x157)
if {$PCBB($CPU)==0} {
### only if booting
### hack to make it unique across processors
###
set PCBB($CPU) [expr -1 * $CPU]
}
console "OS.TCl: entering for cpu $CPU. pc=$pc \n"
set PID($CPU) $PCBB($CPU)
if [catch {currentProcess}] {
# booting
set PROCESS($CPU) "boot"
set OSPID($CPU) boot$CPU
} elseif {(([hex $pc] >= [symbol read vmunix::idle_thread:START])
&& ([hex $pc] <= ([symbol read vmunix::idle_thread:END] + 4)))
|| ((![catch {symbol read vmunix::checkRunq:START}]) &&
([hex $pc] >= [symbol read vmunix::checkRunq:START])
&& ([hex $pc] <= ([symbol read vmunix::checkRunq:END] + 4)))} {
# idle
set PROCESS($CPU) "idle"
set OSPID($CPU) idle$CPU
} else {
set PROCESS($CPU) "someprocess"
set OSPID($CPU) "someprocess$CPU"
}
console "OS.TCL entering for cpu=$CPU with pid=$OSPID($CPU) pcbb=$PCBB($CPU) process=$PROCESS($CPU) \n"
}
proc newproc { pid process comment } {
global CPU PROCESS PID PCBB OSPID
if {($PCBB($CPU) != $PID($CPU))} {
annotation exec osEvent switchOut
set PROCESS($CPU) $process
set OSPID($CPU) $pid
set PID($CPU) $PCBB($CPU)
#console "XXX newproc $comment $pid $process \n"
annotation exec osEvent switchIn
if {$PROCESS($CPU) == "kernel idle"} {
annotation exec osEvent startIdle
}
} else {
console "newproc. Switching to the same (pid,process)=($OSPID($CPU),$PROCESS($CPU)) and same PCBB comment=$comment \n"
}
}
proc currentProcess {} {
global sp
global MEMORY PROCESS PID UU_COMM UTASK_OFFSET UPROC_OFFSET a0 CPU CYCLES
set stack_layout [hex [expr $sp & ~0x3fff]]
set task [symbol read "vmunix::((struct stack_layout *)$stack_layout)->uthread.utask"]
set newPROCESS [symbol read "vmunix::((struct utask *)$task)->uu_comm"]
return $newPROCESS
}
proc currentPID {} {
global sp
global MEMORY PROCESS PID UU_COMM UTASK_OFFSET UPROC_OFFSET a0 CPU CYCLES
set stack_layout [hex [expr $sp & ~0x3fff]]
set pproc [symbol read "vmunix::((struct stack_layout *)$stack_layout)->uthread.proc"]
set newPID [symbol read "vmunix::((struct proc *)$pproc)->p_pid"]
return $newPID
}
proc currentPPID {} {
global sp
global MEMORY PROCESS PID UU_COMM UTASK_OFFSET UPROC_OFFSET a0 CPU CYCLES
set stack_layout [hex [expr $sp & ~0x3fff]]
set pproc [symbol read "vmunix::((struct stack_layout *)$stack_layout)->uthread.proc"]
set ppid [symbol read "vmunix::((struct proc *)$pproc)->p_ppid"]
return $ppid
}
proc ContextSwitch { ptr} {
global MEMORY PROCESS PID UU_COMM UTASK_OFFSET UPROC_OFFSET a0 CPU CYCLES
set stack_layout [hex $ptr]
##
## find base of get_sp()->uthread
##
set task [symbol read "vmunix::((struct stack_layout *)$stack_layout)->uthread.utask"]
set pproc [symbol read "vmunix::((struct stack_layout *)$stack_layout)->uthread.proc"]
set newPROCESS [symbol read "vmunix::((struct utask *)$task)->uu_comm"]
set newPID [symbol read "vmunix::((struct proc *)$pproc)->p_pid"]
if {($newPROCESS != $PROCESS($CPU)) || ($newPID != $OSPID($CPU))} {
newproc $newPID $newPROCESS ContextSwitch
}
}
######################################################
#### Annotations
######################################################
### PALENTRY(0x6c01) == callpal_swpctx
annotation set pc 0x6c01 {
#console "CALL_PAL swpctxt $a0 \n"
set PCBB($CPU) $a0
}
annotation set pc vmunix::idle_thread:START {
#newproc idle$CPU "idle" idle_thread_START
set OSPID($CPU) idle$CPU
set PROCESS($CPU) idle
annotation exec osEvent startIdle
}
annotation set pc vmunix::idle_thread: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" idle_threadEND
}
}
annotation set pc vmunix::swtch:START {
newproc runq$CPU "runq" swtchSTART
}
annotation set pc vmunix::swtch:END {
newproc [currentPID] [currentProcess] swtchEND
}
annotation set pc vmunix::swtch_pri:START {
newproc runq$CPU "runq" swtch_pri_START
}
annotation set pc vmunix::swtch_pri:END {
newproc [currentPID] [currentProcess] swtch_pri_END
}
####
#### This is the key annotation. Ocurs just after the callpal swpctx
####
annotation set pc vmunix::thread_continue {
newproc [currentPID] [currentProcess] thread_continue
}
#annotation set pc vmunix::thread_ex_end {
# console "Reached thread_ex_end \n"
# newproc [currentPID] [currentProcess] thread_ex_end
#}
console "@@@ adding annotation to vmunix::newproc:END\n"
annotation set pc vmunix::newproc:END {
global a1 sp v0
global MEMORY PROCESS PID UU_COMM UTASK_OFFSET UPROC_OFFSET a0 CPU CYCLES CHILD_PID
if {$v0 != 0} {
set th $v0
set ptask [symbol read "vmunix::((struct thread *)$th)->task"]
set newPID [symbol read "vmunix::((struct super_task *)$ptask)->proc.p_pid"]
# child process of the fork
log "newproc in os.tcl: current PID is $OSPID($CPU), new pid is $newPID\n"
set CHILD_OSPID($CPU) $newPID
annotation exec osEvent procstart
# does not cause a process switch
}
}
annotation set pc vmunix::waitf:END {
## process join
global CHILD_PID CPU a3 v0
set CHILD_OSPID($CPU) 0
if {$v0 == 0} {
catch {set CHILD_OSPID($CPU) [Double $a3]} err
}
annotation exec osEvent procwait
}
annotation set pc vmunix::common_exec:END {
annotation exec osEvent switchOut
set PROCESS($CPU) [currentProcess]
annotation exec osEvent procexec
annotation exec osEvent switchIn
}
annotation set pc vmunix::exit:START {
global a0 a1 sp v0 ra
global MEMORY PROCESS PID UU_COMM UTASK_OFFSET UPROC_OFFSET a0 CPU CYCLES
set pproc $a0
set pid [symbol read "vmunix::((struct proc *)$pproc)->p_pid"]
# console "exit:START: current PID is $OSPID($CPU), exiting pid is $pid (ra=$ra)\n"
set sym [symbol find vmunix $ra]
# console "\t ra is in $sym\n"
# annotation exec osEvent procexit
}
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
# should be looking at $IPR(EXC_ADDR)?
console "UTLB: os.tcl\n"
exit
# if {![inUserMode]} {
# annotation exec osEvent endUser
# }
# annotation exec osEvent startKernel
}
###
### 0x70c1 callsys 0x4101 interrupt 0x4381 DTB_FAULT 0x4481 ITB_ACV
### 0x6f41 retsys 0x6fc1 rti
### 0x6241 cserve a2==9 --> jToPal
annotation set exc {
set currentPalEntry($CPU) $PALENTRY($pc)
incr palCodeCount($CPU)
#log "PALCODE $CYCLES $CPU $palCodeCount($CPU) entry excAddr=$IPR(0x10b) entry $PALENTRY($pc)\n"
if {($pc==0x70c1) || ($pc==0x4101) || ($pc==0x4381) ||($pc==0x4081)} {
annotation exec osEvent startKernel
}
if {($pc==0x6f41) || ($pc==0x6fc1)} {
#console "OS.TCL $CYCLES RTI/RETSYS pc=$pc exc=$IPR(0x10b) \n"
annotation exec osEvent endKernel
}
if {($pc==0x6241) && $a2==0x9} {
console "OS.TCL:: cServe jToPal. Pusing extra startPal state\n"
annotation exec osEvent startPal
}
annotation exec osEvent startPal
}
if {0} {
global IPR
set exc_addr $IPR(0x10b)
console "OS.TCL:: EXC $exc_addr $pc $PALENTRY($pc) \n"
if {$exc_addr & 1 } {
incr palCodeCount($CPU) -1
#log "PALCODE $CYCLES $CPU $palCodeCount($CPU) exit\n"
annotation exec osEvent endPal
} elseif [inUserMode] {
annotation exec osEvent endUser
} else {
annotation exec osEvent endKernel
}
annotation exec osEvent startPal
set utlb($CPU) 0
}
annotation set inst rfe {
incr palCodeCount($CPU) -1
#log "PALCODE $CYCLES$CPU $palCodeCount($CPU) exit\n"
annotation exec osEvent endPal
}
##
## synchronization stuff
##
if {0} {
# MP kernel
console "INFO: DigitalUnix multiprocessor\n"
annotation set pc vmunix::fiolock:START {
annotation exec osEvent startSync
}
annotation set pc vmunix::fiolock:END {
annotation exec osEvent endSync
}
annotation set pc vmunix::fiounlock:START {
annotation exec osEvent startSync
}
annotation set pc vmunix::fiounlock:END {
annotation exec osEvent endSync
}
if {0} {
annotation set pc vmunix::simple_lock:START {
annotation exec osEvent startSync
}
annotation set pc vmunix::simple_lock:END {
annotation exec osEvent endSync
}
annotation set pc vmunix::simple_unlock:START {
annotation exec osEvent startSync
}
annotation set pc vmunix::simple_unlock:END {
annotation exec osEvent endSync
}
}
}
}