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

Subversion Repositories openmsp430

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

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: 124 $
33
# $LastChangedBy: olivier.girard $
34
# $LastChangedDate: 2011-10-27 09:38:36 +0200 (Thu, 27 Oct 2011) $
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
        "!"     {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
    }
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
    # Read register value
100
    set reg_val [ReadRegAll]
101
 
102
    # Format answer
103
    set rsp_answer ""
104
    for {set i 0} {$i < [llength $reg_val]} {incr i} {
105
 
106
        regexp {0x(..)(..)} [lindex $reg_val $i] match msb lsb
107
        append rsp_answer "$lsb$msb"
108
    }
109
 
110
    return $rsp_answer
111
}
112
 
113
#-----------------------------------------------------------------------------#
114
# Write CPU registers                                                         #
115
#-----------------------------------------------------------------------------#
116
proc rsp_G {cmd} {
117
 
118
    # Format register value
119
    set num_reg [expr [string length $cmd]/4]
120
 
121
    set reg_val ""
122
    for {set i 0} {$i < $num_reg} {incr i} {
123
 
124
        set lsb "[string index $cmd [expr $i*4+0]][string index $cmd [expr $i*4+1]]"
125
        set msb "[string index $cmd [expr $i*4+2]][string index $cmd [expr $i*4+3]]"
126
        lappend reg_val "0x$msb$lsb"
127
    }
128
 
129
    # Write registers
130
    WriteRegAll $reg_val
131
 
132
    return "OK"
133
}
134
 
135
#-----------------------------------------------------------------------------#
136
# Kill request.                                                               #
137
#-----------------------------------------------------------------------------#
138
proc rsp_k {cmd} {
139
 
140
    # Reset & Stop CPU
141
    ExecutePOR_Halt
142
 
143
    return "-1"
144
}
145
 
146
#-----------------------------------------------------------------------------#
147
# Write length bytes of memory.                                               #
148
#-----------------------------------------------------------------------------#
149
proc rsp_M {cmd} {
150
 
151
    global mem_breakpoint
152
 
153
    # Parse command
154
    regexp {(.*),(.*):(.*)} $cmd match addr length data
155
    set addr   [format %04x "0x$addr"]
156
    set length [format %d   "0x$length"]
157
 
158
    # Format data
159
    set mem_val ""
160
    for {set i 0} {$i<$length} {incr i} {
161
        lappend mem_val "0x[string range $data [expr $i*2] [expr $i*2+1]]"
162
    }
163
 
164
    # Write memory
165 119 olivier.gi
    if {$length==2} {
166
        regexp {(..)(..)} $data match data_lo data_hi
167
        WriteMem      0 "0x$addr" "0x${data_hi}${data_lo}"
168
    } else {
169
        WriteMemQuick8  "0x$addr" $mem_val
170
    }
171 2 olivier.gi
 
172
    # Eventually re-set the software breakpoints in case they have been overwritten
173
    set addr_start [format %d "0x$addr"]
174
    foreach {brk_addr brk_val} [array get mem_breakpoint] {
175
        set brk_addr_dec    [format %d "0x$brk_addr"]
176
        set brk_addr_offset [expr $brk_addr_dec-$addr_start]
177
        if {(0<=$brk_addr_offset) && ($brk_addr_offset<=$length)} {
178
            set mem_breakpoint($brk_addr) [lindex $mem_val $brk_addr_offset]
179
            WriteMem 0 "0x$brk_addr" 0x4343
180
        }
181
    }
182
 
183
    return "OK"
184
}
185
 
186
 
187
#-----------------------------------------------------------------------------#
188
# Read length bytes from memory.                                              #
189
#-----------------------------------------------------------------------------#
190
proc rsp_m {cmd} {
191
 
192
    global mem_breakpoint
193
 
194
    # Parse command
195
    regexp {(.*),(.*)} $cmd match addr length
196
    set addr   [format %04x "0x$addr"]
197
    set length [format %d   "0x$length"]
198
 
199
    # Read memory
200
    set data [ReadMemQuick8  "0x$addr" $length]
201 119 olivier.gi
 
202 2 olivier.gi
 
203
    # Eventually replace read data by the original software breakpoint value
204
    set addr_start [format %d "0x$addr"]
205
    foreach {brk_addr brk_val} [array get mem_breakpoint] {
206
        set brk_addr_dec    [format %d "0x$brk_addr"]
207
        set brk_addr_offset [expr $brk_addr_dec-$addr_start]
208
        if {(0<=$brk_addr_offset) && ($brk_addr_offset<=$length)} {
209
            set data [lreplace $data $brk_addr_offset $brk_addr_offset "0x$mem_breakpoint($brk_addr)"]
210
        }
211
    }
212
 
213
    # Format data
214
    regsub -all {0x} $data {} data
215
    regsub -all { }  $data {} data
216
 
217
    return $data
218
}
219
 
220
 
221
#-----------------------------------------------------------------------------#
222
# Insert breakpoint.                                                          #
223
#-----------------------------------------------------------------------------#
224
proc rsp_Z {sock cmd} {
225
 
226
    global mem_breakpoint
227
 
228
    # Parse command
229
    regexp {(.),(.*),(.*)} $cmd match type addr length
230
    set addr   [format %04x "0x$addr"]
231
 
232
    switch -exact -- $type {
233
        "0"     {# Memory breakpoint
234
                 set mem_breakpoint($addr) [ReadMem 0 "0x$addr"]
235
                 WriteMem 0 "0x$addr" 0x4343
236
                 return "OK"
237
                }
238
 
239
        "1"     {# Hardware breakpoint
240
                 if {[SetHWBreak 1 [format "0x%04x" 0x$addr] 1 0]} {
241
                     return "OK"
242
                 }
243
                 return ""
244
                }
245
 
246
        "2"     {# Write watchpoint
247
                 if {[SetHWBreak 0 [format "0x%04x" 0x$addr] 0 1]} {
248
                     return "OK"
249
                 }
250
                 return ""
251
                }
252
 
253
        "3"     {# Read watchpoint
254
                 if {[SetHWBreak 0 [format "0x%04x" 0x$addr] 1 0]} {
255
                     return "OK"
256
                 }
257
                 return ""
258
                }
259
 
260
        "4"     {# Access watchpoint
261
                 if {[SetHWBreak 0 [format "0x%04x" 0x$addr] 1 1]} {
262
                     return "OK"
263
                 }
264
                 return ""
265
                }
266
 
267
        default {return ""}
268
    }
269
}
270
 
271
#-----------------------------------------------------------------------------#
272
# Remove breakpoint.                                                          #
273
#-----------------------------------------------------------------------------#
274
proc rsp_z {sock cmd} {
275
 
276
    global mem_breakpoint
277
 
278
    # Parse command
279
    regexp {(.),(.*),(.*)} $cmd match type addr length
280
    set addr   [format %04x "0x$addr"]
281
 
282
    switch -exact -- $type {
283
        "0"     {# Memory breakpoint
284
                 WriteMem 0 "0x$addr" $mem_breakpoint($addr)
285
                 unset mem_breakpoint($addr)
286
                 return "OK"
287
                }
288
 
289
        "1"     {# Hardware breakpoint
290
                 if {[ClearHWBreak 1 [format "0x%04x" 0x$addr]]} {
291
                     return "OK"
292
                 }
293
                 return ""
294
                }
295
 
296
        "2"     {# Write watchpoint
297
                 if {[ClearHWBreak 0 [format "0x%04x" 0x$addr]]} {
298
                     return "OK"
299
                 }
300
                 return ""
301
                }
302
 
303
        "3"     {# Read watchpoint
304
                 if {[ClearHWBreak 0 [format "0x%04x" 0x$addr]]} {
305
                     return "OK"
306
                 }
307
                 return ""
308
                }
309
 
310
        "4"     {# Access watchpoint
311
                 if {[ClearHWBreak 0 [format "0x%04x" 0x$addr]]} {
312
                     return "OK"
313
                 }
314
                 return ""
315
                }
316
 
317
        default {return ""}
318
    }
319
}
320
 
321
#-----------------------------------------------------------------------------#
322
# Continue.                                                                   #
323
#-----------------------------------------------------------------------------#
324
proc rsp_c {sock cmd} {
325
 
326
    # Set address if required
327
    if {$cmd!=""} {
328
        set cmd [format %04x "0x$cmd"]
329
        SetPC "0x$cmd"
330
    }
331
 
332
    # Clear status
333
    ClrStatus
334
 
335
    # Continue
336
    ReleaseCPU
337
 
338
 
339
    return [rsp_stop_reply $sock "c"]
340
}
341
 
342
#-----------------------------------------------------------------------------#
343
# Step.                                                                       #
344
#-----------------------------------------------------------------------------#
345
proc rsp_s {sock cmd} {
346
 
347
    # Set address if required
348
    if {$cmd!=""} {
349
        set cmd [format %04x "0x$cmd"]
350
        SetPC "0x$cmd"
351
    }
352
 
353
    # Clear status
354
    ClrStatus
355
 
356 124 olivier.gi
    # Read current PC value
357
    set pc [ReadReg 0]
358
 
359 2 olivier.gi
    # Incremental step
360
    StepCPU
361
 
362 124 olivier.gi
    return [rsp_stop_reply $sock "s" $pc]
363 2 olivier.gi
}
364
 
365
 
366
#-----------------------------------------------------------------------------#
367
# The `C', `c', `S', `s', `vCont', `vAttach', `vRun', `vStopped', and `?'     #
368
# packets can receive any of the below as a reply. Except for `?' and         #
369
# `vStopped', that reply is only returned when the target halts.              #
370
#-----------------------------------------------------------------------------#
371 124 olivier.gi
proc rsp_stop_reply {sock cmd {opt_val "0"}} {
372 2 olivier.gi
 
373
    # Wait until halted
374
    while {![IsHalted]} {
375
 
376
        # Wait a few milliseconds to prevent the gui from freezing
377
        after 100 {set end 1}
378
        vwait end
379
 
380
        # Check if we are interrupted by GDB
381
        fconfigure $sock -blocking 0
382
        set break_char [read -nonewline $sock]
383
        fconfigure $sock -blocking 1
384
        binary scan $break_char H* break_char
385
        if {$break_char=="03"} {
386
            putsVerbose "--> BREAK"
387
            HaltCPU
388
        }
389
    }
390
 
391
    # Read some important registers
392
    set pc [ReadReg 0]
393
    regexp {0x(..)(..)} $pc match pc_hi pc_lo
394
    set r4 [ReadReg 4]
395
    regexp {0x(..)(..)} $r4 match r4_hi r4_lo
396
 
397 124 olivier.gi
        # In case of a single step command, make sure that the PC
398
        # value changes. If not, return an error otherwise GDB will
399
        # end-up in an infinite loop.
400
        if {$cmd == "s"} {
401
                if {$opt_val == $pc} {
402
                        return "E05"
403
                }
404
        }
405
        #return "S05"
406
        return "T0500:$pc_lo$pc_hi;04:$r4_lo$r4_hi;"
407 2 olivier.gi
}
408
 
409
 
410
#-----------------------------------------------------------------------------#
411
#                                                                             #
412
#-----------------------------------------------------------------------------#
413
proc rsp_q {sock cmd} {
414
 
415
       switch -regexp -- $cmd {
416
 
417
        "C"       {set rsp_answer ""}
418
        "Offsets" {set rsp_answer "Text=0;Data=0;Bss=0"}
419
        "Rcmd,.+" {set rsp_answer [rsp_qRcmd $sock $cmd]}
420
        default   {set rsp_answer ""}
421
    }
422
    return $rsp_answer
423
}
424
 
425
#-----------------------------------------------------------------------------#
426
# qRcmd,command'                                                              #
427
#    command (hex encoded) is passed to the local interpreter for execution.  #
428
#    Invalid commands should be reported using the output string. Before the  #
429
#    final result packet, the target may also respond with a number of        #
430
#    intermediate `Ooutput' console output packets. Implementors should note  #
431
#    that providing access to a stubs's interpreter may have security         #
432
#    implications.                                                            #
433
#-----------------------------------------------------------------------------#
434
proc rsp_qRcmd {sock cmd} {
435
 
436
    regsub {^Rcmd,} $cmd {} cmd
437
    set cmd [binary format H* $cmd];  # Convert hex to ascii
438
 
439
    switch -exact -- $cmd {
440
        "erase all" {;# Convert ascii to hex
441
                     binary scan "Erasing target program memory..." H* text1
442
                     binary scan " Erased OK\n"                     H* text2
443
                     ;# Execute erase command
444
                     sendRSPpacket $sock "O$text1"
445
                     EraseROM
446
                     sendRSPpacket $sock "O$text2"
447
                     set rsp_answer "OK"
448
                    }
449
        default     {set rsp_answer "OK"}
450
    }
451
 
452
    return $rsp_answer
453
 
454
}

powered by: WebSVN 2.1.0

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