split startup.tcl file across modules
[openocd.git] / src / target / startup.tcl
1 #########
2
3 # This reset logic may be overridden by board/target/... scripts as needed
4 # to provide a reset that, if possible, is close to a power-up reset.
5 #
6 # Exit requirements include: (a) JTAG must be working, (b) the scan
7 # chain was validated with "jtag arp_init" (or equivalent), (c) nothing
8 # stays in reset. No TAP-specific scans were performed. It's OK if
9 # some targets haven't been reset yet; they may need TAP-specific scans.
10 #
11 # The "mode" values include: halt, init, run (from "reset" command);
12 # startup (at OpenOCD server startup, when JTAG may not yet work); and
13 # potentially more (for reset types like cold, warm, etc)
14 proc init_reset { mode } {
15 jtag arp_init-reset
16 }
17
18
19 global in_process_reset
20 set in_process_reset 0
21
22 # Catch reset recursion
23 proc ocd_process_reset { MODE } {
24 global in_process_reset
25 if {$in_process_reset} {
26 set in_process_reset 0
27 return -code error "'reset' can not be invoked recursively"
28 }
29
30 set in_process_reset 1
31 set success [expr [catch {ocd_process_reset_inner $MODE} result]==0]
32 set in_process_reset 0
33
34 if {$success} {
35 return $result
36 } else {
37 return -code error $result
38 }
39 }
40
41 proc ocd_process_reset_inner { MODE } {
42 set targets [target names]
43
44 # If this target must be halted...
45 set halt -1
46 if { 0 == [string compare $MODE halt] } {
47 set halt 1
48 }
49 if { 0 == [string compare $MODE init] } {
50 set halt 1;
51 }
52 if { 0 == [string compare $MODE run ] } {
53 set halt 0;
54 }
55 if { $halt < 0 } {
56 return -error "Invalid mode: $MODE, must be one of: halt, init, or run";
57 }
58
59 # Target event handlers *might* change which TAPs are enabled
60 # or disabled, so we fire all of them. But don't issue any
61 # target "arp_*" commands, which may issue JTAG transactions,
62 # unless we know the underlying TAP is active.
63 #
64 # NOTE: ARP == "Advanced Reset Process" ... "advanced" is
65 # relative to a previous restrictive scheme
66
67 foreach t $targets {
68 # New event script.
69 $t invoke-event reset-start
70 }
71
72 # Use TRST or TMS/TCK operations to reset all the tap controllers.
73 # TAP reset events get reported; they might enable some taps.
74 init_reset $MODE
75
76 # Examine all targets on enabled taps.
77 foreach t $targets {
78 if {[jtag tapisenabled [$t cget -chain-position]]} {
79 $t arp_examine
80 }
81 }
82
83 # Assert SRST, and report the pre/post events.
84 # Note: no target sees SRST before "pre" or after "post".
85 foreach t $targets {
86 $t invoke-event reset-assert-pre
87 }
88 foreach t $targets {
89 # C code needs to know if we expect to 'halt'
90 if {[jtag tapisenabled [$t cget -chain-position]]} {
91 $t arp_reset assert $halt
92 }
93 }
94 foreach t $targets {
95 $t invoke-event reset-assert-post
96 }
97
98 # Now de-assert SRST, and report the pre/post events.
99 # Note: no target sees !SRST before "pre" or after "post".
100 foreach t $targets {
101 $t invoke-event reset-deassert-pre
102 }
103 foreach t $targets {
104 # Again, de-assert code needs to know if we 'halt'
105 if {[jtag tapisenabled [$t cget -chain-position]]} {
106 $t arp_reset deassert $halt
107 }
108 }
109 foreach t $targets {
110 $t invoke-event reset-deassert-post
111 }
112
113 # Pass 1 - Now wait for any halt (requested as part of reset
114 # assert/deassert) to happen. Ideally it takes effect without
115 # first executing any instructions.
116 if { $halt } {
117 foreach t $targets {
118 if {[jtag tapisenabled [$t cget -chain-position]] == 0} {
119 continue
120 }
121
122 # Wait upto 1 second for target to halt. Why 1sec? Cause
123 # the JTAG tap reset signal might be hooked to a slow
124 # resistor/capacitor circuit - and it might take a while
125 # to charge
126
127 # Catch, but ignore any errors.
128 catch { $t arp_waitstate halted 1000 }
129
130 # Did we succeed?
131 set s [$t curstate]
132
133 if { 0 != [string compare $s "halted" ] } {
134 return -error [format "TARGET: %s - Not halted" $t]
135 }
136 }
137 }
138
139 #Pass 2 - if needed "init"
140 if { 0 == [string compare init $MODE] } {
141 foreach t $targets {
142 if {[jtag tapisenabled [$t cget -chain-position]] == 0} {
143 continue
144 }
145
146 set err [catch "$t arp_waitstate halted 5000"]
147 # Did it halt?
148 if { $err == 0 } {
149 $t invoke-event reset-init
150 }
151 }
152 }
153
154 foreach t $targets {
155 $t invoke-event reset-end
156 }
157 }
158
159 #########
160
161 # Temporary migration aid. May be removed starting in January 2011.
162 proc armv4_5 params {
163 echo "DEPRECATED! use 'arm $params' not 'armv4_5 $params'"
164 arm $params
165 }