bdoor.tcl
4.74 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
#
# 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.
#
###
### bdoor command
###
### Now slightly more complicated than it used to be: index all
### variables with the PID of the bdoor process. This allows
### multiple simultaneous running bdoor processes (as happens,
### for example, during multiple slave startup of a hive system
### with more than two cells)
###
#console "BDOOR.TCL: Setting bdoor ann at [symbol read bdoor::main:START]\n"
### hack until BenW's stuff comes along
set bdoor(main) 0x400aac
set bdoor(mainEval) 0x400adc
set bdoor(mainLoop) 0x400ae8
set bdoor(addr) 0x10000070
set bdoor(countAddr) 0x10000000
# symbol load bdoor $env(SIMOS_DIR)/runtime-files/bdoor
# set bdoor(main) [symbol read bdoor::main:STARTOPT]
# set bdoor(mainEval) [symbol read bdoor::main:eval]
# set bdoor(mainLoop) [symbol read bdoor::main:loop]
# set bdoor(addr) [symbol read bdoor::buf]
# set bdoor(countAddr) [symbol read bdoor::count]
set bdoor(streamEnabled) 0
annotation set pc $bdoor(main) -tag bdoor {
set pid $PID($CPU)
set machine $M($CPU)
set bdoor($machine,$pid,argc) $a0
set bdoor($machine,$pid,argv) $a1
}
annotation set pc $bdoor(mainEval) -tag bdoor {
set pid $PID($CPU)
set machine $M($CPU)
if [info exists bdoor($machine,$pid,argc)] {
# this if test will fail if we are restoring from
# a checkpoint... the 'bdoor doCheckpoint' ran in the
# first execution of simos, setting argc and argv, but
# in the restore we hit the eval annotation first
set argc $bdoor($machine,$pid,argc)
set argv $bdoor($machine,$pid,argv)
if {$argc > 1} {
assert {$PROCESS($CPU) == "bdoor"}
set bdoorString ""
for {set i 1} {$i < $argc} {incr i} {
set theArg $MEMORY([expr $argv+4*$i])
set bdoorString "$bdoorString [readString $theArg]"
# set bdoorString "$bdoorString [symbol read bdoor::((char**)$argv)<$i>]"
}
# console "TCL: $bdoorString\n"
# hack: ensure that stream is only called when this bdoor is
# active and will read the result. If someone tries something
# fancy the pids won't match and the stream will be a nop.
set bdoor(streamEnabled) 1
set errno [catch { eval $bdoorString } msg]
set bdoor(streamEnabled) 0
if {$errno != 0} {
console "BDOOR ERROR: $msg\n"
}
}
unset bdoor($machine,$pid,argc) bdoor($machine,$pid,argv)
}
}
annotation set pc $bdoor(mainLoop) -tag bdoor {
set pid $PID($CPU)
set machine $M($CPU)
if [info exists bdoor($machine,$pid,fid)] {
# this if test will fail if the user is not running
# a stream, or if we are restoring a checkpoint
set fid $bdoor($machine,$pid,fid)
set len $bdoor($machine,$pid,len)
set chunk $bdoor($machine,$pid,chunk)
set sizeLeft [expr $len - ($chunk * 4096)]
set bytes [expr ($sizeLeft < 4096) ? $sizeLeft : 4096]
if {$bytes > 0} {
set MEMORY($bdoor(countAddr)) $bytes
# symbol set bdoor::count $bytes
binary putmem $fid $bdoor(addr) $bytes
incr bdoor($machine,$pid,chunk)
} else {
set MEMORY($bdoor(countAddr)) 0
#symbol set bdoor::count 0
binary close $fid
unset bdoor($machine,$pid,fid) bdoor($machine,$pid,len) bdoor($machine,$pid,chunk)
}
}
}
proc stream {hostFileName} {
global bdoor PID CPU M
if {! $bdoor(streamEnabled)} {
console "TCL BDOOR: can't invoke 'stream' if bdoor process is not active\n"
} else {
set pid $PID($CPU)
set machine $M($CPU)
if [file exists $hostFileName] {
set bdoor($machine,$pid,fid) [binary open $hostFileName r]
set bdoor($machine,$pid,len) [file size $hostFileName]
set bdoor($machine,$pid,chunk) 0
} else {
console "TCL BDOOR: file $hostFileName does not exist\n"
}
}
}
proc streamImmediate {streamData} {
global bdoor PID CPU M
if {! $bdoor(streamEnabled)} {
console "TCL BDOOR: can't invoke 'stream' if bdoor process is not active\n"
} else {
set pid $PID($CPU)
set machine $M($CPU)
set bdoor($machine,$pid,fid) [binary immediate "$streamData"]
set bdoor($machine,$pid,len) [string length $streamData]
set bdoor($machine,$pid,chunk) 0
}
}
registerUserAnns bdoor bdoor