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

Subversion Repositories openmsp430

[/] [openmsp430/] [trunk/] [tools/] [lib/] [tcl-lib/] [dbg_functions.tcl] - Blame information for rev 96

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

Line No. Rev Author Line
1 2 olivier.gi
#------------------------------------------------------------------------------
2
# Copyright (C) 2001 Authors
3
#
4
# This source file may be used and distributed without restriction provided
5
# that this copyright statement is not removed from the file and that any
6
# derivative work contains the original copyright notice and the associated
7
# disclaimer.
8
#
9
# This source file is free software; you can redistribute it and/or modify
10
# it under the terms of the GNU Lesser General Public License as published
11
# by the Free Software Foundation; either version 2.1 of the License, or
12
# (at your option) any later version.
13
#
14
# This source is distributed in the hope that it will be useful, but WITHOUT
15
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17
# License for more details.
18
#
19
# You should have received a copy of the GNU Lesser General Public License
20
# along with this source; if not, write to the Free Software Foundation,
21
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22
#
23
#------------------------------------------------------------------------------
24
# 
25
# File Name:   dbg_functions.tcl
26
#
27 15 olivier.gi
# Author(s):
28
#             - Olivier Girard,    olgirard@gmail.com
29
#
30
#------------------------------------------------------------------------------
31
# $Rev: 96 $
32
# $LastChangedBy: olivier.girard $
33
# $LastChangedDate: 2011-02-27 21:29:35 +0100 (Sun, 27 Feb 2011) $
34
#------------------------------------------------------------------------------
35
#
36 2 olivier.gi
# Description: Main utility functions for the openMSP430 serial debug
37
#             interface.
38
#
39
#       The following functions are implemented according to the SLAA149
40
#     application report from TI (Programming a Flash-Based MSP430 Using the
41
#     JTAG Interface):
42
#
43
#               - ExecutePOR      ()
44
#               - SetPC           (Addr)
45
#               - HaltCPU         ()
46
#               - ReleaseCPU      ()
47
#               - GetDevice       ()
48
#               - ReleaseDevice   (Addr)
49
#               - WriteMem        (Format,    Addr,     Data)
50
#               - WriteMemQuick   (StartAddr, DataArray)
51
#               - ReadMem         (Format,    Addr)
52
#               - ReadMemQuick    (StartAddr, Length)
53
#               - VerifyMem       (StartAddr, DataArray)
54
#
55
#
56
#       The following have been added:
57
#
58
#               - ExecutePOR_Halt ()
59
#               - GetCPU_ID       ()
60
#               - GetCPU_ID_SIZE  ()
61 74 olivier.gi
#               - VerifyCPU_ID    ()
62 2 olivier.gi
#               - WriteReg        (Addr,      Data)
63
#               - WriteRegAll     (DataArray)
64
#               - ReadReg         (Addr)
65
#               - ReadRegAll      ()
66
#               - WriteMemQuick8  (StartAddr, DataArray)
67
#               - ReadMemQuick8   (StartAddr, Length)
68
#               - StepCPU         ()
69
#               - EraseRAM        ()
70
#               - EraseROM        ()
71
#               - InitBreakUnits  ()
72
#               - SetHWBreak      (Type, Addr,      Rd,       Wr)
73
#               - ClearHWBreak    (Type, Addr)
74
#               - IsHalted        ()
75
#               - ClrStatus       ()
76
# 
77
#------------------------------------------------------------------------------
78
 
79
# GLOBAL VARIABLES
80
global hw_break
81
 
82
# SOURCE REQUIRED LIBRARIES
83
source [file dirname [info script]]/dbg_uart.tcl
84
 
85
#=============================================================================#
86
# ExecutePOR ()                                                               #
87
#-----------------------------------------------------------------------------#
88
# Description: Executes a power-up clear (PUC) command.                       #
89
# Arguments  : None.                                                          #
90
# Result     : 0 if error, 1 otherwise.                                       #
91
#=============================================================================#
92
proc ExecutePOR {} {
93
 
94
    set result 1
95
 
96
    # Set PUC
97
    set cpu_ctl_org [dbg_uart_rd CPU_CTL]
98
    set cpu_ctl_new [expr 0x40 | $cpu_ctl_org]
99
    dbg_uart_wr CPU_CTL $cpu_ctl_new
100
 
101
    # Remove PUC, clear break after reset
102
    set cpu_ctl_org [expr 0x5f & $cpu_ctl_org]
103
    dbg_uart_wr CPU_CTL $cpu_ctl_org
104
 
105
    # Check CPU ID
106 74 olivier.gi
    if {![VerifyCPU_ID]} {
107 2 olivier.gi
        set result 0
108
    }
109
 
110
    # Check status: make sure a PUC occured
111
    set cpu_stat_val [dbg_uart_rd CPU_STAT]
112
    set puc_pnd      [expr 0x04 & $cpu_stat_val]
113
    if {![string eq $puc_pnd 4]} {
114
        set result 0
115
    }
116
 
117
    # Clear PUC pending flag
118
    dbg_uart_wr CPU_STAT 0x04
119
 
120
    return $result
121
}
122
 
123
#=============================================================================#
124
# SetPC (Addr)                                                                #
125
#-----------------------------------------------------------------------------#
126
# Description: Loads the target device CPU's program counter (PC) with the    #
127
#              desired 16-bit address.                                        #
128
# Arguments  : Addr - Desired 16-bit PC value (in hexadecimal).               #
129
# Result     : 0 if error, 1 otherwise.                                       #
130
#=============================================================================#
131
proc SetPC {Addr} {
132
 
133
    return [WriteReg 0 $Addr]
134
}
135
 
136
#=============================================================================#
137
# HaltCPU ()                                                                  #
138
#-----------------------------------------------------------------------------#
139
# Description: Sends the target CPU into a controlled, stopped state.         #
140
# Arguments  : None.                                                          #
141
# Result     : 0 if error, 1 otherwise.                                       #
142
#=============================================================================#
143
proc HaltCPU {} {
144
 
145
    set result 1
146
 
147
    # Stop CPU
148
    set cpu_ctl_org [dbg_uart_rd CPU_CTL]
149
    set cpu_ctl_new [expr 0x01 | $cpu_ctl_org]
150
    dbg_uart_wr CPU_CTL $cpu_ctl_new
151
 
152
    # Check status: make sure the CPU halted
153
    set cpu_stat_val [dbg_uart_rd CPU_STAT]
154
    set halted       [expr 0x01 & $cpu_stat_val]
155
    if {![string eq $halted 1]} {
156
        set result 0
157
    }
158
 
159
    return $result
160
}
161
 
162
#=============================================================================#
163
# ReleaseCPU ()                                                               #
164
#-----------------------------------------------------------------------------#
165
# Description: Releases the target device's CPU from the controlled, stopped  #
166
#              state. (Does not release the target device from debug control.)#
167
# Arguments  : None.                                                          #
168
# Result     : 0 if error, 1 otherwise.                                       #
169
#=============================================================================#
170
proc ReleaseCPU {} {
171
 
172
    set result 1
173
 
174
    # Start CPU
175
    set cpu_ctl_org [dbg_uart_rd CPU_CTL]
176
    set cpu_ctl_new [expr 0x02 | $cpu_ctl_org]
177
    dbg_uart_wr CPU_CTL $cpu_ctl_new
178
 
179
    # Check status: make sure the CPU runs
180
    set cpu_stat_val [dbg_uart_rd CPU_STAT]
181
    set halted       [expr 0x01 & $cpu_stat_val]
182
    if {![string eq $halted 0]} {
183
        set result 0
184
    }
185
 
186
    return $result
187
}
188
 
189
#=============================================================================#
190
# GetDevice ()                                                                #
191
#-----------------------------------------------------------------------------#
192
# Description: Takes the target MSP430 device under JTAG control.             #
193
#              Enable the auto-freeze feature of timers when in the CPU is    #
194
#              stopped. This prevents an automatic watchdog reset condition.  #
195
#              Enables software breakpoints.                                  #
196
# Arguments  : None.                                                          #
197
# Result     : 0 if error, 1 otherwise.                                       #
198
#=============================================================================#
199
proc GetDevice {} {
200
 
201
    global hw_break
202
 
203
    # Set UART global variables
204
    if {![info exists ::serial_baudrate]} {
205
        set ::serial_baudrate 9600
206
    }
207
    if {![info exists ::serial_device]} {
208
        set ::serial_device   /dev/ttyUSB0
209
    }
210
 
211
    # Open connection
212
    if {![dbg_uart_connect $::serial_device $::serial_baudrate]} {
213
        return 0
214
    }
215
 
216
    # Enable auto-freeze & software breakpoints
217
    dbg_uart_wr CPU_CTL 0x0018
218
 
219
    # Get number of hardware breakpoints
220
    set hw_break(num) [InitBreakUnits]
221
 
222
    # Check CPU ID
223 87 olivier.gi
    return [VerifyCPU_ID]
224 2 olivier.gi
}
225
 
226
#=============================================================================#
227
# ReleaseDevice (Addr)                                                        #
228
#-----------------------------------------------------------------------------#
229
# Description: Releases the target device from JTAG control; CPU starts       #
230
#              execution at the specified PC address.                         #
231
# Arguments  : Addr - (0xfffe: perform reset; address at reset vector loaded  #
232
#                 into PC; otherwise address specified by Addr loaded into PC #
233
# Result     : 0 if error, 1 otherwise.                                       #
234
#=============================================================================#
235
proc ReleaseDevice {Addr} {
236
 
237
    if {[expr $Addr]==[expr 0xfffe]} {
238
        set result 1
239
        set result [expr $result+[ExecutePOR]]
240
        set result [expr $result+[ReleaseCPU]]
241
    } else {
242
        set result 0
243
        set result [expr $result+[HaltCPU]]
244
        set result [expr $result+[SetPC $Addr]]
245
        set result [expr $result+[ReleaseCPU]]
246
    }
247
 
248
    if {$result==3} {
249
        return 1
250
    } else {
251
        return 0
252
    }
253
}
254
 
255
#=============================================================================#
256
# WriteMem (Format, Addr, Data)                                               #
257
#-----------------------------------------------------------------------------#
258
# Description: Write a single byte or word to a given address (RAM, ROM &     #
259
#              Peripherals.                                                   #
260
# Arguments  : Format - 0 to write a word, 1 to write a byte.                 #
261
#              Addr   - Destination address for data to be written.           #
262
#              Data   - Data value to be written.                             #
263
# Result     : 0 if error, 1 otherwise.                                       #
264
#=============================================================================#
265
proc WriteMem {Format Addr Data} {
266
 
267
    dbg_uart_wr MEM_CNT  0x0000
268
    dbg_uart_wr MEM_ADDR $Addr
269
    dbg_uart_wr MEM_DATA $Data
270
 
271
    if {$Format==0} {
272
        dbg_uart_wr MEM_CTL  0x0003
273
    } else {
274
        dbg_uart_wr MEM_CTL  0x000b
275
    }
276
 
277
    return 1
278
}
279
 
280
#=============================================================================#
281
# WriteMemQuick (StartAddr, DataArray)                                        #
282
#-----------------------------------------------------------------------------#
283
# Description: Writes an array of words into the target device memory (RAM,   #
284
#              ROM & Peripherals.                                             #
285
# Arguments  : StartAddr - Start address of destination memory.               #
286
#              DataArray - List of data to be written (in hexadecimal).       #
287
# Result     : 0 if error, 1 otherwise.                                       #
288
#=============================================================================#
289
proc WriteMemQuick {StartAddr DataArray} {
290
 
291
    if {[llength $DataArray]==1} {
292
        WriteMem 0 $StartAddr $DataArray
293
    } else {
294
 
295
        dbg_uart_wr MEM_CNT  [expr [llength $DataArray]-1]
296
        dbg_uart_wr MEM_ADDR $StartAddr
297
        dbg_uart_wr MEM_CTL  0x0003
298
 
299
        foreach data [split $DataArray] {
300
 
301
            # Format data
302
            set data [format %04x $data]
303
            regexp {(..)(..)} $data match data_msb data_lsb
304
 
305
            # Send data
306
            dbg_uart_tx "0x$data_lsb 0x$data_msb"
307
        }
308
    }
309
    return 1
310
}
311
 
312
#=============================================================================#
313
# ReadMem (Format, Addr)                                                      #
314
#-----------------------------------------------------------------------------#
315
# Description: Read one byte or word from a specified target memory address.  #
316
# Arguments  : Format - 0 to read a word, 1 to read a byte.                   #
317
#              Addr   - Target address for data to be read.                   #
318
# Result     : Data value stored in the target address memory location.       #
319
#=============================================================================#
320
proc ReadMem {Format Addr} {
321
 
322
    dbg_uart_wr MEM_CNT  0x0000
323
    dbg_uart_wr MEM_ADDR $Addr
324
 
325
    if {$Format==0} {
326
        dbg_uart_wr MEM_CTL  0x0001
327
        set mem_val [dbg_uart_rd MEM_DATA]
328
    } else {
329
        dbg_uart_wr MEM_CTL  0x0009
330
        set mem_val [dbg_uart_rd MEM_DATA]
331
        set mem_val [format "0x%02x" $mem_val]
332
    }
333
 
334
    return $mem_val
335
}
336
 
337
#=============================================================================#
338
# ReadMemQuick (StartAddr, Length)                                            #
339
#-----------------------------------------------------------------------------#
340
# Description: Reads an array of words from target memory.                    #
341
# Arguments  : StartAddr - Start address of target memory to be read.         #
342
#              Length    - Number of word to be read.                         #
343
# Result     : List of data values stored in the target memory.               #
344
#=============================================================================#
345
proc ReadMemQuick {StartAddr Length} {
346
 
347
    if {$Length==1} {
348
        set mem_val [ReadMem 0 $StartAddr]
349
    } else {
350
 
351
        dbg_uart_wr MEM_CNT  [expr $Length-1]
352
        dbg_uart_wr MEM_ADDR $StartAddr
353
        dbg_uart_wr MEM_CTL  0x0001
354
 
355
        set mem_val [dbg_uart_rx 0 [expr $Length*2]]
356
    }
357
    return $mem_val
358
}
359
 
360
#=============================================================================#
361
# VerifyMem (StartAddr, DataArray)                                            #
362
#-----------------------------------------------------------------------------#
363
# Description: Performs a program verification over the given memory range.   #
364
# Arguments  : StartAddr - Start address of the memory to be verified.        #
365
#              DataArray - List of reference data (in hexadecimal).           #
366
# Result     : 0 if error, 1 if verification was successful.                  #
367
#=============================================================================#
368 77 olivier.gi
proc VerifyMem {StartAddr DataArray {DumpOnError 0}} {
369 2 olivier.gi
 
370
    dbg_uart_wr MEM_CNT  [expr [llength $DataArray]-1]
371
    dbg_uart_wr MEM_ADDR $StartAddr
372
    dbg_uart_wr MEM_CTL  0x0001
373
 
374
    set mem_val [dbg_uart_rx 0 [expr [llength $DataArray]*2]]
375
 
376 74 olivier.gi
    set    return_val [string equal $DataArray $mem_val]
377
 
378 77 olivier.gi
    if {($return_val==0) && ($DumpOnError==1)} {
379
        file delete -force openmsp430-verifymem-debug-original.mem
380
        file delete -force openmsp430-verifymem-debug-dumped.mem
381
        set fileId [open openmsp430-verifymem-debug-original.mem "w"]
382
        foreach hexCode $DataArray {
383
            puts $fileId $hexCode
384
        }
385
        close $fileId
386
        set fileId [open openmsp430-verifymem-debug-dumped.mem "w"]
387
        foreach hexCode $mem_val {
388
            puts $fileId $hexCode
389
        }
390
        close $fileId
391
    }
392 74 olivier.gi
 
393
    return $return_val
394 2 olivier.gi
}
395
 
396
#=============================================================================#
397
# ExecutePOR_Halt ()                                                          #
398
#-----------------------------------------------------------------------------#
399
# Description: Same as ExecutePOR with the difference that the CPU            #
400
#              automatically goes in Halt mode after reset.                   #
401
# Arguments  : None.                                                          #
402
# Result     : 0 if error, 1 otherwise.                                       #
403
#=============================================================================#
404
proc ExecutePOR_Halt {} {
405
 
406
    set result 1
407
 
408
    # Perform PUC
409
    set cpu_ctl_org [dbg_uart_rd CPU_CTL]
410
    set cpu_ctl_new [expr 0x60 | $cpu_ctl_org]
411
    dbg_uart_wr CPU_CTL $cpu_ctl_new
412
    dbg_uart_wr CPU_CTL $cpu_ctl_org
413
 
414
    # Check CPU ID
415 74 olivier.gi
    if {![VerifyCPU_ID]} {
416 2 olivier.gi
        set result 0
417
    }
418
 
419
    # Check status: make sure a PUC occured and that the CPU is halted
420
    set cpu_stat_val [dbg_uart_rd CPU_STAT]
421
    set puc_pnd      [expr 0x05 & $cpu_stat_val]
422
    if {![string eq $puc_pnd 5]} {
423
        set result 0
424
    }
425
 
426
    # Clear PUC pending flag
427
    dbg_uart_wr CPU_STAT 0x04
428
 
429
    return $result
430
}
431
 
432
#=============================================================================#
433
# GetCPU_ID ()                                                                #
434
#-----------------------------------------------------------------------------#
435
# Description: This function reads the CPU_ID from the target device.         #
436
# Arguments  : None.                                                          #
437
# Result     : Return CPU_ID.                                                 #
438
#=============================================================================#
439
proc GetCPU_ID { } {
440
 
441
    regsub {0x} [dbg_uart_rd CPU_ID_LO] {} cpu_id_lo
442
    regsub {0x} [dbg_uart_rd CPU_ID_HI] {} cpu_id_hi
443
 
444
    return "0x$cpu_id_hi$cpu_id_lo"
445
}
446
 
447
#=============================================================================#
448
# GetCPU_ID_SIZE ()                                                           #
449
#-----------------------------------------------------------------------------#
450
# Description: Returns the ROM and RAM sizes of the connected device.         #
451
# Arguments  : None.                                                          #
452
# Result     : Return "ROM_SIZE RAM_SIZE" in byte.                            #
453
#=============================================================================#
454 74 olivier.gi
proc GetCPU_ID_SIZE {} {
455 2 olivier.gi
 
456
    set cpu_id_full [GetCPU_ID]
457 87 olivier.gi
    regexp {(....)(....)$} $cpu_id_full match rom_size ram_size
458 2 olivier.gi
 
459 87 olivier.gi
    if {[info exists rom_size]} {
460
        set rom_size [expr 0x$rom_size]
461
    } else {
462
        set rom_size -1
463
    }
464
    if {[info exists ram_size]} {
465
        set ram_size [expr 0x$ram_size]
466
    } else {
467
        set ram_size -1
468
    }
469 2 olivier.gi
 
470
    return "$rom_size $ram_size"
471
}
472
 
473
#=============================================================================#
474 74 olivier.gi
# VerifyCPU_ID ()                                                             #
475 2 olivier.gi
#-----------------------------------------------------------------------------#
476
# Description: Read and check the CPU_ID from the target device.              #
477
# Arguments  : None.                                                          #
478
# Result     : 0 if error, 1 otherwise.                                       #
479
#=============================================================================#
480 74 olivier.gi
proc VerifyCPU_ID {} {
481 2 olivier.gi
 
482
    set cpu_id_full [GetCPU_ID]
483
 
484 87 olivier.gi
    if {[string eq "0x00000000" $cpu_id_full] | [string eq "0x" $cpu_id_full]} {
485 74 olivier.gi
        set result 0
486
    } else {
487 2 olivier.gi
        set result 1
488
    }
489
    return $result
490
}
491
 
492
#=============================================================================#
493
# WriteReg (Addr,  Data)                                                      #
494
#-----------------------------------------------------------------------------#
495
# Description: Write a word to the the selected CPU register.                 #
496
# Arguments  : Addr - Target CPU Register number.                             #
497
#              Data - Data value to be written.                               #
498
# Result     : 0 if error, 1 otherwise.                                       #
499
#=============================================================================#
500
proc WriteReg {Addr Data} {
501
 
502
    dbg_uart_wr MEM_CNT  0x0000
503
 
504
    dbg_uart_wr MEM_ADDR $Addr
505
    dbg_uart_wr MEM_DATA $Data
506
    dbg_uart_wr MEM_CTL  0x0007
507
 
508
    return 1
509
}
510
 
511
#=============================================================================#
512
# WriteRegAll (DataArray)                                                     #
513
#-----------------------------------------------------------------------------#
514
# Description: Write all CPU registers.                                       #
515
# Arguments  : DataArray - Data values to be written.                         #
516
# Result     : 0 if error, 1 otherwise.                                       #
517
#=============================================================================#
518
proc WriteRegAll {DataArray} {
519
 
520
    dbg_uart_wr MEM_CNT  [expr [llength $DataArray]-1]
521
    dbg_uart_wr MEM_ADDR 0x0000
522
    dbg_uart_wr MEM_CTL  0x0007
523
 
524
    foreach data [split $DataArray] {
525
 
526
        # Format data
527
        set data [format %04x $data]
528
        regexp {(..)(..)} $data match data_msb data_lsb
529
 
530
        # Send data
531
        dbg_uart_tx "0x$data_lsb 0x$data_msb"
532
    }
533
 
534
    return 1
535
}
536
 
537
#=============================================================================#
538
# ReadReg (Addr)                                                              #
539
#-----------------------------------------------------------------------------#
540
# Description: Read the value from the selected CPU register.                 #
541
# Arguments  : Addr - Target CPU Register number.                             #
542
# Result     : Data value stored in the selected CPU register.                #
543
#=============================================================================#
544
proc ReadReg {Addr} {
545
 
546
    dbg_uart_wr MEM_CNT  0x0000
547
 
548
    dbg_uart_wr MEM_ADDR $Addr
549
    dbg_uart_wr MEM_CTL  0x0005
550
    set reg_val [dbg_uart_rd MEM_DATA]
551
 
552
    return $reg_val
553
}
554
 
555
#=============================================================================#
556
# ReadRegAll ()                                                               #
557
#-----------------------------------------------------------------------------#
558
# Description: Read all CPU registers.                                        #
559
# Arguments  : None.                                                          #
560
# Result     : Current values of all CPU registers.                           #
561
#=============================================================================#
562
proc ReadRegAll {} {
563
 
564
    dbg_uart_wr MEM_CNT  0x000f
565
    dbg_uart_wr MEM_ADDR 0x0000
566
    dbg_uart_wr MEM_CTL  0x0005
567
 
568
    set reg_val [dbg_uart_rx 0 32]
569
 
570
    return $reg_val
571
}
572
 
573
#=============================================================================#
574
# WriteMemQuick8 (StartAddr, DataArray)                                       #
575
#-----------------------------------------------------------------------------#
576
# Description: Writes an array of bytes into the target device memory (RAM,   #
577
#              ROM & Peripherals.                                             #
578
# Arguments  : StartAddr - Start address of destination memory.               #
579
#              DataArray - List of data to be written (in hexadecimal).       #
580
# Result     : 0 if error, 1 otherwise.                                       #
581
#=============================================================================#
582
proc WriteMemQuick8 {StartAddr DataArray} {
583
 
584
    if {[llength $DataArray]==1} {
585
        WriteMem 1 $StartAddr $DataArray
586
    } else {
587
 
588
        dbg_uart_wr MEM_CNT  [expr [llength $DataArray]-1]
589
        dbg_uart_wr MEM_ADDR $StartAddr
590
        dbg_uart_wr MEM_CTL  0x000b
591
 
592
        foreach data [split $DataArray] {
593
 
594
            # Format data
595
            set data [format %02x $data]
596
 
597
            # Send data
598
            dbg_uart_tx "0x$data"
599
        }
600
    }
601
    return 1
602
}
603
 
604
#=============================================================================#
605
# ReadMemQuick8 (StartAddr, Length)                                           #
606
#-----------------------------------------------------------------------------#
607
# Description: Reads an array of bytes from target memory.                    #
608
# Arguments  : StartAddr - Start address of target memory to be read.         #
609
#              Length    - Number of bytes to be read.                        #
610
# Result     : List of data values stored in the target memory.               #
611
#=============================================================================#
612
proc ReadMemQuick8 {StartAddr Length} {
613
 
614
    if {$Length==1} {
615
        set mem_val [ReadMem 1 $StartAddr]
616
    } else {
617
        dbg_uart_wr MEM_CNT  [expr $Length-1]
618
        dbg_uart_wr MEM_ADDR $StartAddr
619
        dbg_uart_wr MEM_CTL  0x0009
620
 
621
        set mem_val [dbg_uart_rx 1 [expr $Length]]
622
    }
623
 
624
    return $mem_val
625
}
626
 
627
#=============================================================================#
628
# StepCPU ()                                                                  #
629
#-----------------------------------------------------------------------------#
630
# Description: Performs a CPU incremental step.                               #
631
# Arguments  : None.                                                          #
632
# Result     : 0 if error, 1 otherwise.                                       #
633
#=============================================================================#
634
proc StepCPU {} {
635
 
636
    # Check if the device is halted. If not, stop it.
637
    set cpu_ctl_val [dbg_uart_rd CPU_CTL]
638
    set cpu_ctl_new [expr 0x04 | $cpu_ctl_val]
639
    dbg_uart_wr CPU_CTL $cpu_ctl_new
640
 
641
    return 1
642
}
643
 
644
#=============================================================================#
645
# EraseRAM ()                                                                 #
646
#-----------------------------------------------------------------------------#
647
# Description: Erase RAM.                                                     #
648
# Arguments  : None.                                                          #
649
# Result     : 0 if error, 1 otherwise.                                       #
650
#=============================================================================#
651
proc EraseRAM {} {
652
 
653
    set ram_size [lindex [GetCPU_ID_SIZE] 1]
654
 
655 87 olivier.gi
    if {$ram_size!=-1} {
656
        set DataArray ""
657
        for {set i 0} {$i<$ram_size} {incr i} {
658
            lappend DataArray 0x00
659
        }
660 2 olivier.gi
 
661 87 olivier.gi
        WriteMemQuick8 $0x0200 $DataArray
662 2 olivier.gi
 
663 87 olivier.gi
        return 1
664
    }
665
    return 0
666 2 olivier.gi
}
667
 
668
#=============================================================================#
669
# EraseROM ()                                                                 #
670
#-----------------------------------------------------------------------------#
671
# Description: Erase ROM.                                                     #
672
# Arguments  : None.                                                          #
673
# Result     : 0 if error, 1 otherwise.                                       #
674
#=============================================================================#
675
proc EraseROM {} {
676
 
677
    set rom_size  [lindex [GetCPU_ID_SIZE] 0]
678
    set rom_start [expr 0x10000-$rom_size]
679
 
680 96 olivier.gi
    if {$rom_size!=-1} {
681 87 olivier.gi
        set DataArray ""
682
        for {set i 0} {$i<$rom_size} {incr i} {
683
            lappend DataArray 0x00
684
        }
685 2 olivier.gi
 
686 87 olivier.gi
        WriteMemQuick8 $rom_start $DataArray
687 2 olivier.gi
 
688 87 olivier.gi
        return 1
689
    }
690
    return 0
691 2 olivier.gi
}
692
 
693
#=============================================================================#
694
# InitBreakUnits()                                                            #
695
#-----------------------------------------------------------------------------#
696
# Description: Initialize the hardware breakpoint units.                      #
697
# Arguments  : None.                                                          #
698
# Result     : Number of hardware breakpoint units.                           #
699
#=============================================================================#
700
proc InitBreakUnits {} {
701
 
702
    set num_brk_units 0
703
    for {set i 0} {$i<4} {incr i} {
704
 
705
        dbg_uart_wr "BRK$i\_ADDR0" 0x1234
706
        set new_val [dbg_uart_rd "BRK$i\_ADDR0"]
707
        if {$new_val=="0x1234"} {
708
            incr num_brk_units
709
            dbg_uart_wr "BRK$i\_CTL"   0x00
710
            dbg_uart_wr "BRK$i\_STAT"  0xff
711
            dbg_uart_wr "BRK$i\_ADDR0" 0x0000
712
            dbg_uart_wr "BRK$i\_ADDR1" 0x0000
713
        }
714
    }
715
    return $num_brk_units
716
}
717
 
718
#=============================================================================#
719
# SetHWBreak(Type, Addr, Rd, Wr)                                              #
720
#-----------------------------------------------------------------------------#
721
# Description: Set data/instruction breakpoint on a given memory address.     #
722
# Arguments  : Type - 1 for instruction break, 0 for data break.              #
723
#              Addr - Memory address of the data breakpoint.                  #
724
#              Rd   - Breakpoint on read access.                              #
725
#              Wr   - Breakpoint on write access.                             #
726
# Result     : 0 if error, 1 otherwise.                                       #
727
#=============================================================================#
728
proc SetHWBreak {Type Addr Rd Wr} {
729
    global hw_break
730
 
731
    # Compute the BRKx_CTL corresponding value
732
    set brk_ctl_ref [format "0x02%x" [expr 8*$Type+4+2*$Wr+$Rd]]
733
 
734
    # First look for utilized units with correct BRKx_CTL attributes
735
    for {set i 0} {$i<$hw_break(num)} {incr i} {
736
        if {[string eq [dbg_uart_rd "BRK$i\_CTL"] $brk_ctl_ref]} {
737
            # Look if there is an address free
738
            set brk_addr0 [dbg_uart_rd "BRK$i\_ADDR0"]
739
            set brk_addr1 [dbg_uart_rd "BRK$i\_ADDR1"]
740
            if {[string eq $brk_addr0 $brk_addr1]} {
741
                dbg_uart_wr "BRK$i\_ADDR1" $Addr
742
                return 1
743
            }
744
        }
745
    }
746
 
747
    # Then look for a free unit
748
    for {set i 0} {$i<$hw_break(num)} {incr i} {
749
        if {[string eq [dbg_uart_rd "BRK$i\_CTL"] 0x00]} {
750
            dbg_uart_wr "BRK$i\_ADDR0" $Addr
751
            dbg_uart_wr "BRK$i\_ADDR1" $Addr
752
            dbg_uart_wr "BRK$i\_CTL"   $brk_ctl_ref
753
            return 1
754
        }
755
    }
756
 
757
    return 0
758
}
759
 
760
#=============================================================================#
761
# ClearHWBreak(Type, Addr)                                                    #
762
#-----------------------------------------------------------------------------#
763
# Description: Clear the data/instruction breakpoint set on the provided      #
764
#              memory address.                                                #
765
# Arguments  : Type - 1 for instruction break, 0 for data break.              #
766
#              Addr - Data address of the breakpoint to be cleared.           #
767
# Result     : 0 if error, 1 otherwise.                                       #
768
#=============================================================================#
769
proc ClearHWBreak {Type Addr} {
770
    global hw_break
771
 
772
    for {set i 0} {$i<$hw_break(num)} {incr i} {
773
        # Check if the unit works on Data or Instructions)
774
        set brk_ctl [dbg_uart_rd "BRK$i\_CTL"]
775
        if {[expr $brk_ctl & 0x08]==[expr 8*$Type]} {
776
 
777
            # Look for the matching address
778
            set brk_addr0 [dbg_uart_rd "BRK$i\_ADDR0"]
779
            set brk_addr1 [dbg_uart_rd "BRK$i\_ADDR1"]
780
 
781
            if {[string eq $brk_addr0 $brk_addr1] && [string eq $brk_addr0 $Addr]} {
782
                dbg_uart_wr "BRK$i\_CTL"   0x00
783
                dbg_uart_wr "BRK$i\_STAT"  0xff
784
                dbg_uart_wr "BRK$i\_ADDR0" 0x0000
785
                dbg_uart_wr "BRK$i\_ADDR1" 0x0000
786
                return 1
787
            }
788
            if {[string eq $brk_addr0 $Addr]} {
789
                dbg_uart_wr "BRK$i\_ADDR0" $brk_addr1
790
                return 1
791
            }
792
            if {[string eq $brk_addr1 $Addr]} {
793
                dbg_uart_wr "BRK$i\_ADDR1" $brk_addr0
794
                return 1
795
            }
796
        }
797
    }
798
    return 1
799
}
800
 
801
#=============================================================================#
802
# IsHalted ()                                                                 #
803
#-----------------------------------------------------------------------------#
804
# Description: Check if the CPU is currently stopped or not.                  #
805
# Arguments  : None.                                                          #
806
# Result     : 0 if CPU is running, 1 if stopped.                             #
807
#=============================================================================#
808
proc IsHalted {} {
809
 
810
    # Check current target status
811
    set cpu_stat_val [dbg_uart_rd CPU_STAT]
812
    set halted       [expr 0x01 & $cpu_stat_val]
813
 
814
    return $halted
815
}
816
 
817
#=============================================================================#
818
# ClrStatus ()                                                                #
819
#-----------------------------------------------------------------------------#
820
# Description: Clear the status bit of the CPU_STAT register.                 #
821
# Arguments  : None.                                                          #
822
# Result     : 0 if error, 1 otherwise.                                       #
823
#=============================================================================#
824
proc ClrStatus {} {
825
 
826
    # Clear status
827
    dbg_uart_wr CPU_STAT  0xff
828
    dbg_uart_wr BRK0_STAT 0xff
829
    dbg_uart_wr BRK1_STAT 0xff
830
    dbg_uart_wr BRK2_STAT 0xff
831
    dbg_uart_wr BRK3_STAT 0xff
832
 
833
    return 1
834
}

powered by: WebSVN 2.1.0

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