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 74

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: 74 $
32
# $LastChangedBy: olivier.girard $
33
# $LastChangedDate: 2010-08-28 21:53:08 +0200 (Sat, 28 Aug 2010) $
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 74 olivier.gi
    if {[VerifyCPU_ID]} {
224 2 olivier.gi
        return 1
225
    } else {
226
        return 0
227
    }
228
}
229
 
230
#=============================================================================#
231
# ReleaseDevice (Addr)                                                        #
232
#-----------------------------------------------------------------------------#
233
# Description: Releases the target device from JTAG control; CPU starts       #
234
#              execution at the specified PC address.                         #
235
# Arguments  : Addr - (0xfffe: perform reset; address at reset vector loaded  #
236
#                 into PC; otherwise address specified by Addr loaded into PC #
237
# Result     : 0 if error, 1 otherwise.                                       #
238
#=============================================================================#
239
proc ReleaseDevice {Addr} {
240
 
241
    if {[expr $Addr]==[expr 0xfffe]} {
242
        set result 1
243
        set result [expr $result+[ExecutePOR]]
244
        set result [expr $result+[ReleaseCPU]]
245
    } else {
246
        set result 0
247
        set result [expr $result+[HaltCPU]]
248
        set result [expr $result+[SetPC $Addr]]
249
        set result [expr $result+[ReleaseCPU]]
250
    }
251
 
252
    if {$result==3} {
253
        return 1
254
    } else {
255
        return 0
256
    }
257
}
258
 
259
#=============================================================================#
260
# WriteMem (Format, Addr, Data)                                               #
261
#-----------------------------------------------------------------------------#
262
# Description: Write a single byte or word to a given address (RAM, ROM &     #
263
#              Peripherals.                                                   #
264
# Arguments  : Format - 0 to write a word, 1 to write a byte.                 #
265
#              Addr   - Destination address for data to be written.           #
266
#              Data   - Data value to be written.                             #
267
# Result     : 0 if error, 1 otherwise.                                       #
268
#=============================================================================#
269
proc WriteMem {Format Addr Data} {
270
 
271
    dbg_uart_wr MEM_CNT  0x0000
272
    dbg_uart_wr MEM_ADDR $Addr
273
    dbg_uart_wr MEM_DATA $Data
274
 
275
    if {$Format==0} {
276
        dbg_uart_wr MEM_CTL  0x0003
277
    } else {
278
        dbg_uart_wr MEM_CTL  0x000b
279
    }
280
 
281
    return 1
282
}
283
 
284
#=============================================================================#
285
# WriteMemQuick (StartAddr, DataArray)                                        #
286
#-----------------------------------------------------------------------------#
287
# Description: Writes an array of words into the target device memory (RAM,   #
288
#              ROM & Peripherals.                                             #
289
# Arguments  : StartAddr - Start address of destination memory.               #
290
#              DataArray - List of data to be written (in hexadecimal).       #
291
# Result     : 0 if error, 1 otherwise.                                       #
292
#=============================================================================#
293
proc WriteMemQuick {StartAddr DataArray} {
294
 
295
    if {[llength $DataArray]==1} {
296
        WriteMem 0 $StartAddr $DataArray
297
    } else {
298
 
299
        dbg_uart_wr MEM_CNT  [expr [llength $DataArray]-1]
300
        dbg_uart_wr MEM_ADDR $StartAddr
301
        dbg_uart_wr MEM_CTL  0x0003
302
 
303
        foreach data [split $DataArray] {
304
 
305
            # Format data
306
            set data [format %04x $data]
307
            regexp {(..)(..)} $data match data_msb data_lsb
308
 
309
            # Send data
310
            dbg_uart_tx "0x$data_lsb 0x$data_msb"
311
        }
312
    }
313
    return 1
314
}
315
 
316
#=============================================================================#
317
# ReadMem (Format, Addr)                                                      #
318
#-----------------------------------------------------------------------------#
319
# Description: Read one byte or word from a specified target memory address.  #
320
# Arguments  : Format - 0 to read a word, 1 to read a byte.                   #
321
#              Addr   - Target address for data to be read.                   #
322
# Result     : Data value stored in the target address memory location.       #
323
#=============================================================================#
324
proc ReadMem {Format Addr} {
325
 
326
    dbg_uart_wr MEM_CNT  0x0000
327
    dbg_uart_wr MEM_ADDR $Addr
328
 
329
    if {$Format==0} {
330
        dbg_uart_wr MEM_CTL  0x0001
331
        set mem_val [dbg_uart_rd MEM_DATA]
332
    } else {
333
        dbg_uart_wr MEM_CTL  0x0009
334
        set mem_val [dbg_uart_rd MEM_DATA]
335
        set mem_val [format "0x%02x" $mem_val]
336
    }
337
 
338
    return $mem_val
339
}
340
 
341
#=============================================================================#
342
# ReadMemQuick (StartAddr, Length)                                            #
343
#-----------------------------------------------------------------------------#
344
# Description: Reads an array of words from target memory.                    #
345
# Arguments  : StartAddr - Start address of target memory to be read.         #
346
#              Length    - Number of word to be read.                         #
347
# Result     : List of data values stored in the target memory.               #
348
#=============================================================================#
349
proc ReadMemQuick {StartAddr Length} {
350
 
351
    if {$Length==1} {
352
        set mem_val [ReadMem 0 $StartAddr]
353
    } else {
354
 
355
        dbg_uart_wr MEM_CNT  [expr $Length-1]
356
        dbg_uart_wr MEM_ADDR $StartAddr
357
        dbg_uart_wr MEM_CTL  0x0001
358
 
359
        set mem_val [dbg_uart_rx 0 [expr $Length*2]]
360
    }
361
    return $mem_val
362
}
363
 
364
#=============================================================================#
365
# VerifyMem (StartAddr, DataArray)                                            #
366
#-----------------------------------------------------------------------------#
367
# Description: Performs a program verification over the given memory range.   #
368
# Arguments  : StartAddr - Start address of the memory to be verified.        #
369
#              DataArray - List of reference data (in hexadecimal).           #
370
# Result     : 0 if error, 1 if verification was successful.                  #
371
#=============================================================================#
372
proc VerifyMem {StartAddr DataArray} {
373
 
374
    dbg_uart_wr MEM_CNT  [expr [llength $DataArray]-1]
375
    dbg_uart_wr MEM_ADDR $StartAddr
376
    dbg_uart_wr MEM_CTL  0x0001
377
 
378
    set mem_val [dbg_uart_rx 0 [expr [llength $DataArray]*2]]
379
 
380 74 olivier.gi
    set    return_val [string equal $DataArray $mem_val]
381
 
382
    #if {$return_val==0} {
383
    #   puts $DataArray
384
    #   puts $mem_val
385
    #}
386
 
387
    return $return_val
388 2 olivier.gi
}
389
 
390
#=============================================================================#
391
# ExecutePOR_Halt ()                                                          #
392
#-----------------------------------------------------------------------------#
393
# Description: Same as ExecutePOR with the difference that the CPU            #
394
#              automatically goes in Halt mode after reset.                   #
395
# Arguments  : None.                                                          #
396
# Result     : 0 if error, 1 otherwise.                                       #
397
#=============================================================================#
398
proc ExecutePOR_Halt {} {
399
 
400
    set result 1
401
 
402
    # Perform PUC
403
    set cpu_ctl_org [dbg_uart_rd CPU_CTL]
404
    set cpu_ctl_new [expr 0x60 | $cpu_ctl_org]
405
    dbg_uart_wr CPU_CTL $cpu_ctl_new
406
    dbg_uart_wr CPU_CTL $cpu_ctl_org
407
 
408
    # Check CPU ID
409 74 olivier.gi
    if {![VerifyCPU_ID]} {
410 2 olivier.gi
        set result 0
411
    }
412
 
413
    # Check status: make sure a PUC occured and that the CPU is halted
414
    set cpu_stat_val [dbg_uart_rd CPU_STAT]
415
    set puc_pnd      [expr 0x05 & $cpu_stat_val]
416
    if {![string eq $puc_pnd 5]} {
417
        set result 0
418
    }
419
 
420
    # Clear PUC pending flag
421
    dbg_uart_wr CPU_STAT 0x04
422
 
423
    return $result
424
}
425
 
426
#=============================================================================#
427
# GetCPU_ID ()                                                                #
428
#-----------------------------------------------------------------------------#
429
# Description: This function reads the CPU_ID from the target device.         #
430
# Arguments  : None.                                                          #
431
# Result     : Return CPU_ID.                                                 #
432
#=============================================================================#
433
proc GetCPU_ID { } {
434
 
435
    regsub {0x} [dbg_uart_rd CPU_ID_LO] {} cpu_id_lo
436
    regsub {0x} [dbg_uart_rd CPU_ID_HI] {} cpu_id_hi
437
 
438
    return "0x$cpu_id_hi$cpu_id_lo"
439
}
440
 
441
#=============================================================================#
442
# GetCPU_ID_SIZE ()                                                           #
443
#-----------------------------------------------------------------------------#
444
# Description: Returns the ROM and RAM sizes of the connected device.         #
445
# Arguments  : None.                                                          #
446
# Result     : Return "ROM_SIZE RAM_SIZE" in byte.                            #
447
#=============================================================================#
448 74 olivier.gi
proc GetCPU_ID_SIZE {} {
449 2 olivier.gi
 
450
    set cpu_id_full [GetCPU_ID]
451 74 olivier.gi
    regexp {(....)(....)$} $cpu_id_full match rom_width ram_width
452 2 olivier.gi
 
453 74 olivier.gi
    set rom_size [expr 0x$rom_width]
454
    set ram_size [expr 0x$ram_width]
455 2 olivier.gi
 
456
    return "$rom_size $ram_size"
457
}
458
 
459
#=============================================================================#
460 74 olivier.gi
# VerifyCPU_ID ()                                                             #
461 2 olivier.gi
#-----------------------------------------------------------------------------#
462
# Description: Read and check the CPU_ID from the target device.              #
463
# Arguments  : None.                                                          #
464
# Result     : 0 if error, 1 otherwise.                                       #
465
#=============================================================================#
466 74 olivier.gi
proc VerifyCPU_ID {} {
467 2 olivier.gi
 
468
    set cpu_id_full [GetCPU_ID]
469
 
470 74 olivier.gi
    if {[string eq "0x00000000" $cpu_id_full]} {
471
        set result 0
472
    } else {
473 2 olivier.gi
        set result 1
474
    }
475
    return $result
476
}
477
 
478
#=============================================================================#
479
# WriteReg (Addr,  Data)                                                      #
480
#-----------------------------------------------------------------------------#
481
# Description: Write a word to the the selected CPU register.                 #
482
# Arguments  : Addr - Target CPU Register number.                             #
483
#              Data - Data value to be written.                               #
484
# Result     : 0 if error, 1 otherwise.                                       #
485
#=============================================================================#
486
proc WriteReg {Addr Data} {
487
 
488
    dbg_uart_wr MEM_CNT  0x0000
489
 
490
    dbg_uart_wr MEM_ADDR $Addr
491
    dbg_uart_wr MEM_DATA $Data
492
    dbg_uart_wr MEM_CTL  0x0007
493
 
494
    return 1
495
}
496
 
497
#=============================================================================#
498
# WriteRegAll (DataArray)                                                     #
499
#-----------------------------------------------------------------------------#
500
# Description: Write all CPU registers.                                       #
501
# Arguments  : DataArray - Data values to be written.                         #
502
# Result     : 0 if error, 1 otherwise.                                       #
503
#=============================================================================#
504
proc WriteRegAll {DataArray} {
505
 
506
    dbg_uart_wr MEM_CNT  [expr [llength $DataArray]-1]
507
    dbg_uart_wr MEM_ADDR 0x0000
508
    dbg_uart_wr MEM_CTL  0x0007
509
 
510
    foreach data [split $DataArray] {
511
 
512
        # Format data
513
        set data [format %04x $data]
514
        regexp {(..)(..)} $data match data_msb data_lsb
515
 
516
        # Send data
517
        dbg_uart_tx "0x$data_lsb 0x$data_msb"
518
    }
519
 
520
    return 1
521
}
522
 
523
#=============================================================================#
524
# ReadReg (Addr)                                                              #
525
#-----------------------------------------------------------------------------#
526
# Description: Read the value from the selected CPU register.                 #
527
# Arguments  : Addr - Target CPU Register number.                             #
528
# Result     : Data value stored in the selected CPU register.                #
529
#=============================================================================#
530
proc ReadReg {Addr} {
531
 
532
    dbg_uart_wr MEM_CNT  0x0000
533
 
534
    dbg_uart_wr MEM_ADDR $Addr
535
    dbg_uart_wr MEM_CTL  0x0005
536
    set reg_val [dbg_uart_rd MEM_DATA]
537
 
538
    return $reg_val
539
}
540
 
541
#=============================================================================#
542
# ReadRegAll ()                                                               #
543
#-----------------------------------------------------------------------------#
544
# Description: Read all CPU registers.                                        #
545
# Arguments  : None.                                                          #
546
# Result     : Current values of all CPU registers.                           #
547
#=============================================================================#
548
proc ReadRegAll {} {
549
 
550
    dbg_uart_wr MEM_CNT  0x000f
551
    dbg_uart_wr MEM_ADDR 0x0000
552
    dbg_uart_wr MEM_CTL  0x0005
553
 
554
    set reg_val [dbg_uart_rx 0 32]
555
 
556
    return $reg_val
557
}
558
 
559
#=============================================================================#
560
# WriteMemQuick8 (StartAddr, DataArray)                                       #
561
#-----------------------------------------------------------------------------#
562
# Description: Writes an array of bytes into the target device memory (RAM,   #
563
#              ROM & Peripherals.                                             #
564
# Arguments  : StartAddr - Start address of destination memory.               #
565
#              DataArray - List of data to be written (in hexadecimal).       #
566
# Result     : 0 if error, 1 otherwise.                                       #
567
#=============================================================================#
568
proc WriteMemQuick8 {StartAddr DataArray} {
569
 
570
    if {[llength $DataArray]==1} {
571
        WriteMem 1 $StartAddr $DataArray
572
    } else {
573
 
574
        dbg_uart_wr MEM_CNT  [expr [llength $DataArray]-1]
575
        dbg_uart_wr MEM_ADDR $StartAddr
576
        dbg_uart_wr MEM_CTL  0x000b
577
 
578
        foreach data [split $DataArray] {
579
 
580
            # Format data
581
            set data [format %02x $data]
582
 
583
            # Send data
584
            dbg_uart_tx "0x$data"
585
        }
586
    }
587
    return 1
588
}
589
 
590
#=============================================================================#
591
# ReadMemQuick8 (StartAddr, Length)                                           #
592
#-----------------------------------------------------------------------------#
593
# Description: Reads an array of bytes from target memory.                    #
594
# Arguments  : StartAddr - Start address of target memory to be read.         #
595
#              Length    - Number of bytes to be read.                        #
596
# Result     : List of data values stored in the target memory.               #
597
#=============================================================================#
598
proc ReadMemQuick8 {StartAddr Length} {
599
 
600
    if {$Length==1} {
601
        set mem_val [ReadMem 1 $StartAddr]
602
    } else {
603
        dbg_uart_wr MEM_CNT  [expr $Length-1]
604
        dbg_uart_wr MEM_ADDR $StartAddr
605
        dbg_uart_wr MEM_CTL  0x0009
606
 
607
        set mem_val [dbg_uart_rx 1 [expr $Length]]
608
    }
609
 
610
    return $mem_val
611
}
612
 
613
#=============================================================================#
614
# StepCPU ()                                                                  #
615
#-----------------------------------------------------------------------------#
616
# Description: Performs a CPU incremental step.                               #
617
# Arguments  : None.                                                          #
618
# Result     : 0 if error, 1 otherwise.                                       #
619
#=============================================================================#
620
proc StepCPU {} {
621
 
622
    # Check if the device is halted. If not, stop it.
623
    set cpu_ctl_val [dbg_uart_rd CPU_CTL]
624
    set cpu_ctl_new [expr 0x04 | $cpu_ctl_val]
625
    dbg_uart_wr CPU_CTL $cpu_ctl_new
626
 
627
    return 1
628
}
629
 
630
#=============================================================================#
631
# EraseRAM ()                                                                 #
632
#-----------------------------------------------------------------------------#
633
# Description: Erase RAM.                                                     #
634
# Arguments  : None.                                                          #
635
# Result     : 0 if error, 1 otherwise.                                       #
636
#=============================================================================#
637
proc EraseRAM {} {
638
 
639
    set ram_size [lindex [GetCPU_ID_SIZE] 1]
640
 
641
    set DataArray ""
642
    for {set i 0} {$i<$ram_size} {incr i} {
643
        lappend DataArray 0x00
644
    }
645
 
646
    WriteMemQuick8 $0x0200 $DataArray
647
 
648
    return 1
649
}
650
 
651
#=============================================================================#
652
# EraseROM ()                                                                 #
653
#-----------------------------------------------------------------------------#
654
# Description: Erase ROM.                                                     #
655
# Arguments  : None.                                                          #
656
# Result     : 0 if error, 1 otherwise.                                       #
657
#=============================================================================#
658
proc EraseROM {} {
659
 
660
    set rom_size  [lindex [GetCPU_ID_SIZE] 0]
661
    set rom_start [expr 0x10000-$rom_size]
662
 
663
    set DataArray ""
664
    for {set i 0} {$i<$rom_size} {incr i} {
665
        lappend DataArray 0x00
666
    }
667
 
668
    WriteMemQuick8 $rom_start $DataArray
669
 
670
    return 1
671
}
672
 
673
#=============================================================================#
674
# InitBreakUnits()                                                            #
675
#-----------------------------------------------------------------------------#
676
# Description: Initialize the hardware breakpoint units.                      #
677
# Arguments  : None.                                                          #
678
# Result     : Number of hardware breakpoint units.                           #
679
#=============================================================================#
680
proc InitBreakUnits {} {
681
 
682
    set num_brk_units 0
683
    for {set i 0} {$i<4} {incr i} {
684
 
685
        dbg_uart_wr "BRK$i\_ADDR0" 0x1234
686
        set new_val [dbg_uart_rd "BRK$i\_ADDR0"]
687
        if {$new_val=="0x1234"} {
688
            incr num_brk_units
689
            dbg_uart_wr "BRK$i\_CTL"   0x00
690
            dbg_uart_wr "BRK$i\_STAT"  0xff
691
            dbg_uart_wr "BRK$i\_ADDR0" 0x0000
692
            dbg_uart_wr "BRK$i\_ADDR1" 0x0000
693
        }
694
    }
695
    return $num_brk_units
696
}
697
 
698
#=============================================================================#
699
# SetHWBreak(Type, Addr, Rd, Wr)                                              #
700
#-----------------------------------------------------------------------------#
701
# Description: Set data/instruction breakpoint on a given memory address.     #
702
# Arguments  : Type - 1 for instruction break, 0 for data break.              #
703
#              Addr - Memory address of the data breakpoint.                  #
704
#              Rd   - Breakpoint on read access.                              #
705
#              Wr   - Breakpoint on write access.                             #
706
# Result     : 0 if error, 1 otherwise.                                       #
707
#=============================================================================#
708
proc SetHWBreak {Type Addr Rd Wr} {
709
    global hw_break
710
 
711
    # Compute the BRKx_CTL corresponding value
712
    set brk_ctl_ref [format "0x02%x" [expr 8*$Type+4+2*$Wr+$Rd]]
713
 
714
    # First look for utilized units with correct BRKx_CTL attributes
715
    for {set i 0} {$i<$hw_break(num)} {incr i} {
716
        if {[string eq [dbg_uart_rd "BRK$i\_CTL"] $brk_ctl_ref]} {
717
            # Look if there is an address free
718
            set brk_addr0 [dbg_uart_rd "BRK$i\_ADDR0"]
719
            set brk_addr1 [dbg_uart_rd "BRK$i\_ADDR1"]
720
            if {[string eq $brk_addr0 $brk_addr1]} {
721
                dbg_uart_wr "BRK$i\_ADDR1" $Addr
722
                return 1
723
            }
724
        }
725
    }
726
 
727
    # Then look for a free unit
728
    for {set i 0} {$i<$hw_break(num)} {incr i} {
729
        if {[string eq [dbg_uart_rd "BRK$i\_CTL"] 0x00]} {
730
            dbg_uart_wr "BRK$i\_ADDR0" $Addr
731
            dbg_uart_wr "BRK$i\_ADDR1" $Addr
732
            dbg_uart_wr "BRK$i\_CTL"   $brk_ctl_ref
733
            return 1
734
        }
735
    }
736
 
737
    return 0
738
}
739
 
740
#=============================================================================#
741
# ClearHWBreak(Type, Addr)                                                    #
742
#-----------------------------------------------------------------------------#
743
# Description: Clear the data/instruction breakpoint set on the provided      #
744
#              memory address.                                                #
745
# Arguments  : Type - 1 for instruction break, 0 for data break.              #
746
#              Addr - Data address of the breakpoint to be cleared.           #
747
# Result     : 0 if error, 1 otherwise.                                       #
748
#=============================================================================#
749
proc ClearHWBreak {Type Addr} {
750
    global hw_break
751
 
752
    for {set i 0} {$i<$hw_break(num)} {incr i} {
753
        # Check if the unit works on Data or Instructions)
754
        set brk_ctl [dbg_uart_rd "BRK$i\_CTL"]
755
        if {[expr $brk_ctl & 0x08]==[expr 8*$Type]} {
756
 
757
            # Look for the matching address
758
            set brk_addr0 [dbg_uart_rd "BRK$i\_ADDR0"]
759
            set brk_addr1 [dbg_uart_rd "BRK$i\_ADDR1"]
760
 
761
            if {[string eq $brk_addr0 $brk_addr1] && [string eq $brk_addr0 $Addr]} {
762
                dbg_uart_wr "BRK$i\_CTL"   0x00
763
                dbg_uart_wr "BRK$i\_STAT"  0xff
764
                dbg_uart_wr "BRK$i\_ADDR0" 0x0000
765
                dbg_uart_wr "BRK$i\_ADDR1" 0x0000
766
                return 1
767
            }
768
            if {[string eq $brk_addr0 $Addr]} {
769
                dbg_uart_wr "BRK$i\_ADDR0" $brk_addr1
770
                return 1
771
            }
772
            if {[string eq $brk_addr1 $Addr]} {
773
                dbg_uart_wr "BRK$i\_ADDR1" $brk_addr0
774
                return 1
775
            }
776
        }
777
    }
778
    return 1
779
}
780
 
781
#=============================================================================#
782
# IsHalted ()                                                                 #
783
#-----------------------------------------------------------------------------#
784
# Description: Check if the CPU is currently stopped or not.                  #
785
# Arguments  : None.                                                          #
786
# Result     : 0 if CPU is running, 1 if stopped.                             #
787
#=============================================================================#
788
proc IsHalted {} {
789
 
790
    # Check current target status
791
    set cpu_stat_val [dbg_uart_rd CPU_STAT]
792
    set halted       [expr 0x01 & $cpu_stat_val]
793
 
794
    return $halted
795
}
796
 
797
#=============================================================================#
798
# ClrStatus ()                                                                #
799
#-----------------------------------------------------------------------------#
800
# Description: Clear the status bit of the CPU_STAT register.                 #
801
# Arguments  : None.                                                          #
802
# Result     : 0 if error, 1 otherwise.                                       #
803
#=============================================================================#
804
proc ClrStatus {} {
805
 
806
    # Clear status
807
    dbg_uart_wr CPU_STAT  0xff
808
    dbg_uart_wr BRK0_STAT 0xff
809
    dbg_uart_wr BRK1_STAT 0xff
810
    dbg_uart_wr BRK2_STAT 0xff
811
    dbg_uart_wr BRK3_STAT 0xff
812
 
813
    return 1
814
}

powered by: WebSVN 2.1.0

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