OpenCores
URL https://opencores.org/ocsvn/openmsp430/openmsp430/trunk

Subversion Repositories openmsp430

[/] [openmsp430/] [trunk/] [tools/] [openmsp430-gdbproxy/] [commands.tcl] - Blame information for rev 158

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 olivier.gi
#!/usr/bin/wish
2
#------------------------------------------------------------------------------
3
# Copyright (C) 2001 Authors
4
#
5
# This source file may be used and distributed without restriction provided
6
# that this copyright statement is not removed from the file and that any
7
# derivative work contains the original copyright notice and the associated
8
# disclaimer.
9
#
10
# This source file is free software; you can redistribute it and/or modify
11
# it under the terms of the GNU Lesser General Public License as published
12
# by the Free Software Foundation; either version 2.1 of the License, or
13
# (at your option) any later version.
14
#
15
# This source is distributed in the hope that it will be useful, but WITHOUT
16
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18
# License for more details.
19
#
20
# You should have received a copy of the GNU Lesser General Public License
21
# along with this source; if not, write to the Free Software Foundation,
22
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23
#
24
#------------------------------------------------------------------------------
25
# 
26
# File Name: commands.tcl
27
# 
28 15 olivier.gi
# Author(s):
29
#             - Olivier Girard,    olgirard@gmail.com
30
#
31 2 olivier.gi
#------------------------------------------------------------------------------
32 15 olivier.gi
# $Rev: 158 $
33
# $LastChangedBy: olivier.girard $
34
# $LastChangedDate: 2012-10-15 23:49:09 +0200 (Mon, 15 Oct 2012) $
35
#------------------------------------------------------------------------------
36 2 olivier.gi
 
37
global mem_breakpoint
38
 
39
###############################################################################
40
#                                                                             #
41
#                              RSP COMMAND PARSER                             #
42
#                                                                             #
43
###############################################################################
44
 
45
proc rspParse {sock rsp_cmd} {
46
 
47
    set rsp_answer ""
48
    set cmd_tail [string range $rsp_cmd 1 [string length $rsp_cmd]]
49
 
50
    switch -exact -- [string index $rsp_cmd 0] {
51 158 olivier.gi
        "!"     {set rsp_answer "OK"}
52
        "?"     {set rsp_answer [rsp_stop_reply $sock "?"]}
53
        "A"     {}
54
        "b"     {}
55
        "c"     {set rsp_answer [rsp_c $sock $cmd_tail]}
56
        "C"     {set rsp_answer [rsp_c $sock $cmd_tail]}
57
        "D"     {}
58
        "F"     {}
59
        "g"     {set rsp_answer [rsp_g]}
60
        "G"     {set rsp_answer [rsp_G $cmd_tail]}
61
        "H"     {set rsp_answer ""}
62
        "i"     {}
63
        "I"     {}
64
        "k"     {set rsp_answer [rsp_k $cmd_tail]}
65
        "m"     {set rsp_answer [rsp_m $cmd_tail]}
66
        "M"     {set rsp_answer [rsp_M $cmd_tail]}
67
        "p"     {}
68
        "P"     {}
69
        "q"     {set rsp_answer [rsp_q $sock $cmd_tail]}
70
        "Q"     {}
71
        "R"     {}
72
        "s"     {set rsp_answer [rsp_s $sock $cmd_tail]}
73
        "S"     {set rsp_answer [rsp_s $sock $cmd_tail]}
74
        "t"     {}
75
        "T"     {}
76
        "v"     {}
77
        "X"     {}
78
        "z"     {set rsp_answer [rsp_z $sock $cmd_tail]}
79
        "Z"     {set rsp_answer [rsp_Z $sock $cmd_tail]}
80
        default {}
81 2 olivier.gi
    }
82
 
83
 
84
    return $rsp_answer
85
}
86
 
87
 
88
###############################################################################
89
#                                                                             #
90
#                                   RSP COMMANDS                              #
91
#                                                                             #
92
###############################################################################
93
 
94
#-----------------------------------------------------------------------------#
95
# Read CPU registers                                                          #
96
#-----------------------------------------------------------------------------#
97
proc rsp_g {} {
98
 
99 158 olivier.gi
    global CpuNr
100
 
101 2 olivier.gi
    # Read register value
102 158 olivier.gi
    set reg_val [ReadRegAll $CpuNr]
103 2 olivier.gi
 
104
    # Format answer
105
    set rsp_answer ""
106
    for {set i 0} {$i < [llength $reg_val]} {incr i} {
107
 
108 158 olivier.gi
        regexp {0x(..)(..)} [lindex $reg_val $i] match msb lsb
109
        append rsp_answer "$lsb$msb"
110 2 olivier.gi
    }
111
 
112
    return $rsp_answer
113
}
114
 
115
#-----------------------------------------------------------------------------#
116
# Write CPU registers                                                         #
117
#-----------------------------------------------------------------------------#
118
proc rsp_G {cmd} {
119
 
120 158 olivier.gi
    global CpuNr
121
 
122 2 olivier.gi
    # Format register value
123
    set num_reg [expr [string length $cmd]/4]
124
 
125
    set reg_val ""
126
    for {set i 0} {$i < $num_reg} {incr i} {
127
 
128 158 olivier.gi
        set lsb "[string index $cmd [expr $i*4+0]][string index $cmd [expr $i*4+1]]"
129
        set msb "[string index $cmd [expr $i*4+2]][string index $cmd [expr $i*4+3]]"
130
        lappend reg_val "0x$msb$lsb"
131 2 olivier.gi
    }
132
 
133
    # Write registers
134 158 olivier.gi
    WriteRegAll $CpuNr $reg_val
135 2 olivier.gi
 
136
    return "OK"
137
}
138
 
139
#-----------------------------------------------------------------------------#
140
# Kill request.                                                               #
141
#-----------------------------------------------------------------------------#
142
proc rsp_k {cmd} {
143
 
144 158 olivier.gi
    global CpuNr
145
 
146 2 olivier.gi
    # Reset & Stop CPU
147 158 olivier.gi
    ExecutePOR_Halt $CpuNr
148 2 olivier.gi
 
149
    return "-1"
150
}
151
 
152
#-----------------------------------------------------------------------------#
153
# Write length bytes of memory.                                               #
154
#-----------------------------------------------------------------------------#
155
proc rsp_M {cmd} {
156
 
157
    global mem_breakpoint
158 158 olivier.gi
    global CpuNr
159 2 olivier.gi
 
160
    # Parse command
161
    regexp {(.*),(.*):(.*)} $cmd match addr length data
162
    set addr   [format %04x "0x$addr"]
163
    set length [format %d   "0x$length"]
164
 
165
    # Format data
166
    set mem_val ""
167
    for {set i 0} {$i<$length} {incr i} {
168 158 olivier.gi
        lappend mem_val "0x[string range $data [expr $i*2] [expr $i*2+1]]"
169 2 olivier.gi
    }
170
 
171
    # Write memory
172 119 olivier.gi
    if {$length==2} {
173 158 olivier.gi
        regexp {(..)(..)} $data match data_lo data_hi
174
        WriteMem       $CpuNr 0 "0x$addr" "0x${data_hi}${data_lo}"
175 119 olivier.gi
    } else {
176 158 olivier.gi
        WriteMemQuick8 $CpuNr   "0x$addr" $mem_val
177 119 olivier.gi
    }
178 2 olivier.gi
 
179
    # Eventually re-set the software breakpoints in case they have been overwritten
180
    set addr_start [format %d "0x$addr"]
181
    foreach {brk_addr brk_val} [array get mem_breakpoint] {
182 158 olivier.gi
        set brk_addr_dec    [format %d "0x$brk_addr"]
183
        set brk_addr_offset [expr $brk_addr_dec-$addr_start]
184
        if {(0<=$brk_addr_offset) && ($brk_addr_offset<=$length)} {
185
            set mem_breakpoint($brk_addr) [lindex $mem_val $brk_addr_offset]
186
            WriteMem $CpuNr 0 "0x$brk_addr" 0x4343
187
        }
188 2 olivier.gi
    }
189
 
190
    return "OK"
191
}
192
 
193
 
194
#-----------------------------------------------------------------------------#
195
# Read length bytes from memory.                                              #
196
#-----------------------------------------------------------------------------#
197
proc rsp_m {cmd} {
198
 
199
    global mem_breakpoint
200 158 olivier.gi
    global CpuNr
201 2 olivier.gi
 
202
    # Parse command
203
    regexp {(.*),(.*)} $cmd match addr length
204
    set addr   [format %04x "0x$addr"]
205
    set length [format %d   "0x$length"]
206
 
207
    # Read memory
208 158 olivier.gi
    set data [ReadMemQuick8  $CpuNr "0x$addr" $length]
209 119 olivier.gi
 
210 2 olivier.gi
 
211
    # Eventually replace read data by the original software breakpoint value
212
    set addr_start [format %d "0x$addr"]
213
    foreach {brk_addr brk_val} [array get mem_breakpoint] {
214 158 olivier.gi
        set brk_addr_dec    [format %d "0x$brk_addr"]
215
        set brk_addr_offset [expr $brk_addr_dec-$addr_start]
216
        if {(0<=$brk_addr_offset) && ($brk_addr_offset<=$length)} {
217
            set data [lreplace $data $brk_addr_offset $brk_addr_offset "0x$mem_breakpoint($brk_addr)"]
218
        }
219 2 olivier.gi
    }
220
 
221
    # Format data
222
    regsub -all {0x} $data {} data
223
    regsub -all { }  $data {} data
224
 
225
    return $data
226
}
227
 
228
 
229
#-----------------------------------------------------------------------------#
230
# Insert breakpoint.                                                          #
231
#-----------------------------------------------------------------------------#
232
proc rsp_Z {sock cmd} {
233
 
234
    global mem_breakpoint
235 158 olivier.gi
    global CpuNr
236 2 olivier.gi
 
237
    # Parse command
238
    regexp {(.),(.*),(.*)} $cmd match type addr length
239
    set addr   [format %04x "0x$addr"]
240
 
241
    switch -exact -- $type {
242 158 olivier.gi
        "0"     {# Memory breakpoint
243
                 set mem_breakpoint($addr) [ReadMem $CpuNr 0 "0x$addr"]
244
                 WriteMem $CpuNr 0 "0x$addr" 0x4343
245
                 return "OK"
246 2 olivier.gi
                }
247
 
248 158 olivier.gi
        "1"     {# Hardware breakpoint
249
                 if {[SetHWBreak $CpuNr 1 [format "0x%04x" 0x$addr] 1 0]} {
250
                     return "OK"
251
                 }
252
                 return ""
253 2 olivier.gi
                }
254
 
255 158 olivier.gi
        "2"     {# Write watchpoint
256
                 if {[SetHWBreak $CpuNr 0 [format "0x%04x" 0x$addr] 0 1]} {
257
                     return "OK"
258
                 }
259
                 return ""
260 2 olivier.gi
                }
261
 
262 158 olivier.gi
        "3"     {# Read watchpoint
263
                 if {[SetHWBreak $CpuNr 0 [format "0x%04x" 0x$addr] 1 0]} {
264
                     return "OK"
265
                 }
266
                 return ""
267 2 olivier.gi
                }
268
 
269 158 olivier.gi
        "4"     {# Access watchpoint
270
                 if {[SetHWBreak $CpuNr 0 [format "0x%04x" 0x$addr] 1 1]} {
271
                     return "OK"
272
                 }
273
                 return ""
274 2 olivier.gi
                }
275
 
276 158 olivier.gi
        default {return ""}
277 2 olivier.gi
    }
278
}
279
 
280
#-----------------------------------------------------------------------------#
281
# Remove breakpoint.                                                          #
282
#-----------------------------------------------------------------------------#
283
proc rsp_z {sock cmd} {
284
 
285
    global mem_breakpoint
286 158 olivier.gi
    global CpuNr
287 2 olivier.gi
 
288
    # Parse command
289
    regexp {(.),(.*),(.*)} $cmd match type addr length
290
    set addr   [format %04x "0x$addr"]
291
 
292
    switch -exact -- $type {
293 158 olivier.gi
        "0"     {# Memory breakpoint
294
                 WriteMem $CpuNr 0 "0x$addr" $mem_breakpoint($addr)
295
                 unset mem_breakpoint($addr)
296
                 return "OK"
297 2 olivier.gi
                }
298
 
299 158 olivier.gi
        "1"     {# Hardware breakpoint
300
                 if {[ClearHWBreak $CpuNr 1 [format "0x%04x" 0x$addr]]} {
301
                     return "OK"
302
                 }
303
                 return ""
304 2 olivier.gi
                }
305
 
306 158 olivier.gi
        "2"     {# Write watchpoint
307
                 if {[ClearHWBreak $CpuNr 0 [format "0x%04x" 0x$addr]]} {
308
                     return "OK"
309
                 }
310
                 return ""
311 2 olivier.gi
                }
312
 
313 158 olivier.gi
        "3"     {# Read watchpoint
314
                 if {[ClearHWBreak $CpuNr 0 [format "0x%04x" 0x$addr]]} {
315
                     return "OK"
316
                 }
317
                 return ""
318 2 olivier.gi
                }
319
 
320 158 olivier.gi
        "4"     {# Access watchpoint
321
                 if {[ClearHWBreak $CpuNr 0 [format "0x%04x" 0x$addr]]} {
322
                     return "OK"
323
                 }
324
                 return ""
325 2 olivier.gi
                }
326
 
327 158 olivier.gi
        default {return ""}
328 2 olivier.gi
    }
329
}
330
 
331
#-----------------------------------------------------------------------------#
332
# Continue.                                                                   #
333
#-----------------------------------------------------------------------------#
334
proc rsp_c {sock cmd} {
335
 
336 158 olivier.gi
    global CpuNr
337
 
338 2 olivier.gi
    # Set address if required
339
    if {$cmd!=""} {
340 158 olivier.gi
        set cmd [format %04x "0x$cmd"]
341
        SetPC $CpuNr "0x$cmd"
342 2 olivier.gi
    }
343
 
344
    # Clear status
345 158 olivier.gi
    ClrStatus  $CpuNr
346 2 olivier.gi
 
347
    # Continue
348 158 olivier.gi
    ReleaseCPU $CpuNr
349 2 olivier.gi
 
350
 
351
    return [rsp_stop_reply $sock "c"]
352
}
353
 
354
#-----------------------------------------------------------------------------#
355
# Step.                                                                       #
356
#-----------------------------------------------------------------------------#
357
proc rsp_s {sock cmd} {
358
 
359 158 olivier.gi
    global CpuNr
360
 
361 2 olivier.gi
    # Set address if required
362
    if {$cmd!=""} {
363 158 olivier.gi
        set cmd [format %04x "0x$cmd"]
364
        SetPC $CpuNr "0x$cmd"
365 2 olivier.gi
    }
366
 
367
    # Clear status
368 158 olivier.gi
    ClrStatus $CpuNr
369 2 olivier.gi
 
370 124 olivier.gi
    # Read current PC value
371 158 olivier.gi
    set pc [ReadReg $CpuNr 0]
372 124 olivier.gi
 
373 2 olivier.gi
    # Incremental step
374 158 olivier.gi
    StepCPU $CpuNr
375 2 olivier.gi
 
376 124 olivier.gi
    return [rsp_stop_reply $sock "s" $pc]
377 2 olivier.gi
}
378
 
379
 
380
#-----------------------------------------------------------------------------#
381
# The `C', `c', `S', `s', `vCont', `vAttach', `vRun', `vStopped', and `?'     #
382
# packets can receive any of the below as a reply. Except for `?' and         #
383
# `vStopped', that reply is only returned when the target halts.              #
384
#-----------------------------------------------------------------------------#
385 124 olivier.gi
proc rsp_stop_reply {sock cmd {opt_val "0"}} {
386 2 olivier.gi
 
387 158 olivier.gi
    global CpuNr
388
 
389 2 olivier.gi
    # Wait until halted
390 158 olivier.gi
    while {![IsHalted $CpuNr]} {
391 2 olivier.gi
 
392 158 olivier.gi
        # Wait a few milliseconds to prevent the gui from freezing
393
        after 100 {set end 1}
394
        vwait end
395 2 olivier.gi
 
396 158 olivier.gi
        # Check if we are interrupted by GDB
397
        fconfigure $sock -blocking 0
398
        set break_char [read -nonewline $sock]
399
        fconfigure $sock -blocking 1
400
        binary scan $break_char H* break_char
401
        if {$break_char=="03"} {
402
            putsVerbose "--> BREAK"
403
            HaltCPU $CpuNr
404
        }
405 2 olivier.gi
    }
406
 
407
    # Read some important registers
408 158 olivier.gi
    set pc [ReadReg $CpuNr 0]
409 2 olivier.gi
    regexp {0x(..)(..)} $pc match pc_hi pc_lo
410 158 olivier.gi
    set r4 [ReadReg $CpuNr 4]
411 2 olivier.gi
    regexp {0x(..)(..)} $r4 match r4_hi r4_lo
412
 
413 158 olivier.gi
        # In case of a single step command, make sure that the PC
414
        # value changes. If not, return an error otherwise GDB will
415
        # end-up in an infinite loop.
416
        if {$cmd == "s"} {
417
                if {$opt_val == $pc} {
418
                        return "E05"
419
                }
420
        }
421
        #return "S05"
422
        return "T0500:$pc_lo$pc_hi;04:$r4_lo$r4_hi;"
423 2 olivier.gi
}
424
 
425
 
426
#-----------------------------------------------------------------------------#
427
#                                                                             #
428
#-----------------------------------------------------------------------------#
429
proc rsp_q {sock cmd} {
430
 
431
       switch -regexp -- $cmd {
432
 
433 158 olivier.gi
        "C"       {set rsp_answer ""}
434
        "Offsets" {set rsp_answer "Text=0;Data=0;Bss=0"}
435
        "Rcmd,.+" {set rsp_answer [rsp_qRcmd $sock $cmd]}
436
        default   {set rsp_answer ""}
437 2 olivier.gi
    }
438
    return $rsp_answer
439
}
440
 
441
#-----------------------------------------------------------------------------#
442
# qRcmd,command'                                                              #
443
#    command (hex encoded) is passed to the local interpreter for execution.  #
444
#    Invalid commands should be reported using the output string. Before the  #
445
#    final result packet, the target may also respond with a number of        #
446
#    intermediate `Ooutput' console output packets. Implementors should note  #
447
#    that providing access to a stubs's interpreter may have security         #
448
#    implications.                                                            #
449
#-----------------------------------------------------------------------------#
450
proc rsp_qRcmd {sock cmd} {
451
 
452 158 olivier.gi
    global CpuNr
453
 
454 2 olivier.gi
    regsub {^Rcmd,} $cmd {} cmd
455
    set cmd [binary format H* $cmd];  # Convert hex to ascii
456
 
457
    switch -exact -- $cmd {
458 158 olivier.gi
        "erase all" {;# Convert ascii to hex
459
                     binary scan "Erasing target program memory..." H* text1
460
                     binary scan " Erased OK\n"                     H* text2
461
                     ;# Execute erase command
462
                     sendRSPpacket $sock "O$text1"
463
                     EraseROM $CpuNr
464
                     sendRSPpacket $sock "O$text2"
465
                     set rsp_answer "OK"
466 2 olivier.gi
                    }
467 158 olivier.gi
        default     {set rsp_answer "OK"}
468 2 olivier.gi
    }
469
 
470
    return $rsp_answer
471
 
472
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.