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 40

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: 15 $
32
# $LastChangedBy: olivier.girard $
33
# $LastChangedDate: 2009-08-04 22:41:47 +0200 (Tue, 04 Aug 2009) $
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
#               - VerifyCPU_ID    (CPU_ID)
62
#               - 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
    if {![VerifyCPU_ID 0x4d5350]} {
107
        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
    if {[VerifyCPU_ID 0x4d5350]} {
224
        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
    return [string equal $DataArray $mem_val]
381
}
382
 
383
#=============================================================================#
384
# ExecutePOR_Halt ()                                                          #
385
#-----------------------------------------------------------------------------#
386
# Description: Same as ExecutePOR with the difference that the CPU            #
387
#              automatically goes in Halt mode after reset.                   #
388
# Arguments  : None.                                                          #
389
# Result     : 0 if error, 1 otherwise.                                       #
390
#=============================================================================#
391
proc ExecutePOR_Halt {} {
392
 
393
    set result 1
394
 
395
    # Perform PUC
396
    set cpu_ctl_org [dbg_uart_rd CPU_CTL]
397
    set cpu_ctl_new [expr 0x60 | $cpu_ctl_org]
398
    dbg_uart_wr CPU_CTL $cpu_ctl_new
399
    dbg_uart_wr CPU_CTL $cpu_ctl_org
400
 
401
    # Check CPU ID
402
    if {![VerifyCPU_ID 0x4d5350]} {
403
        set result 0
404
    }
405
 
406
    # Check status: make sure a PUC occured and that the CPU is halted
407
    set cpu_stat_val [dbg_uart_rd CPU_STAT]
408
    set puc_pnd      [expr 0x05 & $cpu_stat_val]
409
    if {![string eq $puc_pnd 5]} {
410
        set result 0
411
    }
412
 
413
    # Clear PUC pending flag
414
    dbg_uart_wr CPU_STAT 0x04
415
 
416
    return $result
417
}
418
 
419
#=============================================================================#
420
# GetCPU_ID ()                                                                #
421
#-----------------------------------------------------------------------------#
422
# Description: This function reads the CPU_ID from the target device.         #
423
# Arguments  : None.                                                          #
424
# Result     : Return CPU_ID.                                                 #
425
#=============================================================================#
426
proc GetCPU_ID { } {
427
 
428
    regsub {0x} [dbg_uart_rd CPU_ID_LO] {} cpu_id_lo
429
    regsub {0x} [dbg_uart_rd CPU_ID_HI] {} cpu_id_hi
430
 
431
    return "0x$cpu_id_hi$cpu_id_lo"
432
}
433
 
434
#=============================================================================#
435
# GetCPU_ID_SIZE ()                                                           #
436
#-----------------------------------------------------------------------------#
437
# Description: Returns the ROM and RAM sizes of the connected device.         #
438
# Arguments  : None.                                                          #
439
# Result     : Return "ROM_SIZE RAM_SIZE" in byte.                            #
440
#=============================================================================#
441
proc GetCPU_ID_SIZE { } {
442
 
443
    set cpu_id_full [GetCPU_ID]
444
    regexp {(.)(.)$} $cpu_id_full match rom_width ram_width
445
 
446
    set rom_size [expr (1<<0x$rom_width)*2]
447
    set ram_size [expr (1<<0x$ram_width)*2]
448
 
449
    return "$rom_size $ram_size"
450
}
451
 
452
#=============================================================================#
453
# VerifyCPU_ID (uint32 CPU_ID)                                                #
454
#-----------------------------------------------------------------------------#
455
# Description: Read and check the CPU_ID from the target device.              #
456
# Arguments  : None.                                                          #
457
# Result     : 0 if error, 1 otherwise.                                       #
458
#=============================================================================#
459
proc VerifyCPU_ID {cpu_id} {
460
 
461
    set cpu_id_full [GetCPU_ID]
462
    regsub {..$} $cpu_id_full {} cpu_id_hi
463
 
464
    if {[string eq $cpu_id $cpu_id_hi]} {
465
        set result 1
466
    } else {
467
        set result 0
468
    }
469
    return $result
470
}
471
 
472
#=============================================================================#
473
# WriteReg (Addr,  Data)                                                      #
474
#-----------------------------------------------------------------------------#
475
# Description: Write a word to the the selected CPU register.                 #
476
# Arguments  : Addr - Target CPU Register number.                             #
477
#              Data - Data value to be written.                               #
478
# Result     : 0 if error, 1 otherwise.                                       #
479
#=============================================================================#
480
proc WriteReg {Addr Data} {
481
 
482
    dbg_uart_wr MEM_CNT  0x0000
483
 
484
    dbg_uart_wr MEM_ADDR $Addr
485
    dbg_uart_wr MEM_DATA $Data
486
    dbg_uart_wr MEM_CTL  0x0007
487
 
488
    return 1
489
}
490
 
491
#=============================================================================#
492
# WriteRegAll (DataArray)                                                     #
493
#-----------------------------------------------------------------------------#
494
# Description: Write all CPU registers.                                       #
495
# Arguments  : DataArray - Data values to be written.                         #
496
# Result     : 0 if error, 1 otherwise.                                       #
497
#=============================================================================#
498
proc WriteRegAll {DataArray} {
499
 
500
    dbg_uart_wr MEM_CNT  [expr [llength $DataArray]-1]
501
    dbg_uart_wr MEM_ADDR 0x0000
502
    dbg_uart_wr MEM_CTL  0x0007
503
 
504
    foreach data [split $DataArray] {
505
 
506
        # Format data
507
        set data [format %04x $data]
508
        regexp {(..)(..)} $data match data_msb data_lsb
509
 
510
        # Send data
511
        dbg_uart_tx "0x$data_lsb 0x$data_msb"
512
    }
513
 
514
    return 1
515
}
516
 
517
#=============================================================================#
518
# ReadReg (Addr)                                                              #
519
#-----------------------------------------------------------------------------#
520
# Description: Read the value from the selected CPU register.                 #
521
# Arguments  : Addr - Target CPU Register number.                             #
522
# Result     : Data value stored in the selected CPU register.                #
523
#=============================================================================#
524
proc ReadReg {Addr} {
525
 
526
    dbg_uart_wr MEM_CNT  0x0000
527
 
528
    dbg_uart_wr MEM_ADDR $Addr
529
    dbg_uart_wr MEM_CTL  0x0005
530
    set reg_val [dbg_uart_rd MEM_DATA]
531
 
532
    return $reg_val
533
}
534
 
535
#=============================================================================#
536
# ReadRegAll ()                                                               #
537
#-----------------------------------------------------------------------------#
538
# Description: Read all CPU registers.                                        #
539
# Arguments  : None.                                                          #
540
# Result     : Current values of all CPU registers.                           #
541
#=============================================================================#
542
proc ReadRegAll {} {
543
 
544
    dbg_uart_wr MEM_CNT  0x000f
545
    dbg_uart_wr MEM_ADDR 0x0000
546
    dbg_uart_wr MEM_CTL  0x0005
547
 
548
    set reg_val [dbg_uart_rx 0 32]
549
 
550
    return $reg_val
551
}
552
 
553
#=============================================================================#
554
# WriteMemQuick8 (StartAddr, DataArray)                                       #
555
#-----------------------------------------------------------------------------#
556
# Description: Writes an array of bytes into the target device memory (RAM,   #
557
#              ROM & Peripherals.                                             #
558
# Arguments  : StartAddr - Start address of destination memory.               #
559
#              DataArray - List of data to be written (in hexadecimal).       #
560
# Result     : 0 if error, 1 otherwise.                                       #
561
#=============================================================================#
562
proc WriteMemQuick8 {StartAddr DataArray} {
563
 
564
    if {[llength $DataArray]==1} {
565
        WriteMem 1 $StartAddr $DataArray
566
    } else {
567
 
568
        dbg_uart_wr MEM_CNT  [expr [llength $DataArray]-1]
569
        dbg_uart_wr MEM_ADDR $StartAddr
570
        dbg_uart_wr MEM_CTL  0x000b
571
 
572
        foreach data [split $DataArray] {
573
 
574
            # Format data
575
            set data [format %02x $data]
576
 
577
            # Send data
578
            dbg_uart_tx "0x$data"
579
        }
580
    }
581
    return 1
582
}
583
 
584
#=============================================================================#
585
# ReadMemQuick8 (StartAddr, Length)                                           #
586
#-----------------------------------------------------------------------------#
587
# Description: Reads an array of bytes from target memory.                    #
588
# Arguments  : StartAddr - Start address of target memory to be read.         #
589
#              Length    - Number of bytes to be read.                        #
590
# Result     : List of data values stored in the target memory.               #
591
#=============================================================================#
592
proc ReadMemQuick8 {StartAddr Length} {
593
 
594
    if {$Length==1} {
595
        set mem_val [ReadMem 1 $StartAddr]
596
    } else {
597
        dbg_uart_wr MEM_CNT  [expr $Length-1]
598
        dbg_uart_wr MEM_ADDR $StartAddr
599
        dbg_uart_wr MEM_CTL  0x0009
600
 
601
        set mem_val [dbg_uart_rx 1 [expr $Length]]
602
    }
603
 
604
    return $mem_val
605
}
606
 
607
#=============================================================================#
608
# StepCPU ()                                                                  #
609
#-----------------------------------------------------------------------------#
610
# Description: Performs a CPU incremental step.                               #
611
# Arguments  : None.                                                          #
612
# Result     : 0 if error, 1 otherwise.                                       #
613
#=============================================================================#
614
proc StepCPU {} {
615
 
616
    # Check if the device is halted. If not, stop it.
617
    set cpu_ctl_val [dbg_uart_rd CPU_CTL]
618
    set cpu_ctl_new [expr 0x04 | $cpu_ctl_val]
619
    dbg_uart_wr CPU_CTL $cpu_ctl_new
620
 
621
    return 1
622
}
623
 
624
#=============================================================================#
625
# EraseRAM ()                                                                 #
626
#-----------------------------------------------------------------------------#
627
# Description: Erase RAM.                                                     #
628
# Arguments  : None.                                                          #
629
# Result     : 0 if error, 1 otherwise.                                       #
630
#=============================================================================#
631
proc EraseRAM {} {
632
 
633
    set ram_size [lindex [GetCPU_ID_SIZE] 1]
634
 
635
    set DataArray ""
636
    for {set i 0} {$i<$ram_size} {incr i} {
637
        lappend DataArray 0x00
638
    }
639
 
640
    WriteMemQuick8 $0x0200 $DataArray
641
 
642
    return 1
643
}
644
 
645
#=============================================================================#
646
# EraseROM ()                                                                 #
647
#-----------------------------------------------------------------------------#
648
# Description: Erase ROM.                                                     #
649
# Arguments  : None.                                                          #
650
# Result     : 0 if error, 1 otherwise.                                       #
651
#=============================================================================#
652
proc EraseROM {} {
653
 
654
    set rom_size  [lindex [GetCPU_ID_SIZE] 0]
655
    set rom_start [expr 0x10000-$rom_size]
656
 
657
    set DataArray ""
658
    for {set i 0} {$i<$rom_size} {incr i} {
659
        lappend DataArray 0x00
660
    }
661
 
662
    WriteMemQuick8 $rom_start $DataArray
663
 
664
    return 1
665
}
666
 
667
#=============================================================================#
668
# InitBreakUnits()                                                            #
669
#-----------------------------------------------------------------------------#
670
# Description: Initialize the hardware breakpoint units.                      #
671
# Arguments  : None.                                                          #
672
# Result     : Number of hardware breakpoint units.                           #
673
#=============================================================================#
674
proc InitBreakUnits {} {
675
 
676
    set num_brk_units 0
677
    for {set i 0} {$i<4} {incr i} {
678
 
679
        dbg_uart_wr "BRK$i\_ADDR0" 0x1234
680
        set new_val [dbg_uart_rd "BRK$i\_ADDR0"]
681
        if {$new_val=="0x1234"} {
682
            incr num_brk_units
683
            dbg_uart_wr "BRK$i\_CTL"   0x00
684
            dbg_uart_wr "BRK$i\_STAT"  0xff
685
            dbg_uart_wr "BRK$i\_ADDR0" 0x0000
686
            dbg_uart_wr "BRK$i\_ADDR1" 0x0000
687
        }
688
    }
689
    return $num_brk_units
690
}
691
 
692
#=============================================================================#
693
# SetHWBreak(Type, Addr, Rd, Wr)                                              #
694
#-----------------------------------------------------------------------------#
695
# Description: Set data/instruction breakpoint on a given memory address.     #
696
# Arguments  : Type - 1 for instruction break, 0 for data break.              #
697
#              Addr - Memory address of the data breakpoint.                  #
698
#              Rd   - Breakpoint on read access.                              #
699
#              Wr   - Breakpoint on write access.                             #
700
# Result     : 0 if error, 1 otherwise.                                       #
701
#=============================================================================#
702
proc SetHWBreak {Type Addr Rd Wr} {
703
    global hw_break
704
 
705
    # Compute the BRKx_CTL corresponding value
706
    set brk_ctl_ref [format "0x02%x" [expr 8*$Type+4+2*$Wr+$Rd]]
707
 
708
    # First look for utilized units with correct BRKx_CTL attributes
709
    for {set i 0} {$i<$hw_break(num)} {incr i} {
710
        if {[string eq [dbg_uart_rd "BRK$i\_CTL"] $brk_ctl_ref]} {
711
            # Look if there is an address free
712
            set brk_addr0 [dbg_uart_rd "BRK$i\_ADDR0"]
713
            set brk_addr1 [dbg_uart_rd "BRK$i\_ADDR1"]
714
            if {[string eq $brk_addr0 $brk_addr1]} {
715
                dbg_uart_wr "BRK$i\_ADDR1" $Addr
716
                return 1
717
            }
718
        }
719
    }
720
 
721
    # Then look for a free unit
722
    for {set i 0} {$i<$hw_break(num)} {incr i} {
723
        if {[string eq [dbg_uart_rd "BRK$i\_CTL"] 0x00]} {
724
            dbg_uart_wr "BRK$i\_ADDR0" $Addr
725
            dbg_uart_wr "BRK$i\_ADDR1" $Addr
726
            dbg_uart_wr "BRK$i\_CTL"   $brk_ctl_ref
727
            return 1
728
        }
729
    }
730
 
731
    return 0
732
}
733
 
734
#=============================================================================#
735
# ClearHWBreak(Type, Addr)                                                    #
736
#-----------------------------------------------------------------------------#
737
# Description: Clear the data/instruction breakpoint set on the provided      #
738
#              memory address.                                                #
739
# Arguments  : Type - 1 for instruction break, 0 for data break.              #
740
#              Addr - Data address of the breakpoint to be cleared.           #
741
# Result     : 0 if error, 1 otherwise.                                       #
742
#=============================================================================#
743
proc ClearHWBreak {Type Addr} {
744
    global hw_break
745
 
746
    for {set i 0} {$i<$hw_break(num)} {incr i} {
747
        # Check if the unit works on Data or Instructions)
748
        set brk_ctl [dbg_uart_rd "BRK$i\_CTL"]
749
        if {[expr $brk_ctl & 0x08]==[expr 8*$Type]} {
750
 
751
            # Look for the matching address
752
            set brk_addr0 [dbg_uart_rd "BRK$i\_ADDR0"]
753
            set brk_addr1 [dbg_uart_rd "BRK$i\_ADDR1"]
754
 
755
            if {[string eq $brk_addr0 $brk_addr1] && [string eq $brk_addr0 $Addr]} {
756
                dbg_uart_wr "BRK$i\_CTL"   0x00
757
                dbg_uart_wr "BRK$i\_STAT"  0xff
758
                dbg_uart_wr "BRK$i\_ADDR0" 0x0000
759
                dbg_uart_wr "BRK$i\_ADDR1" 0x0000
760
                return 1
761
            }
762
            if {[string eq $brk_addr0 $Addr]} {
763
                dbg_uart_wr "BRK$i\_ADDR0" $brk_addr1
764
                return 1
765
            }
766
            if {[string eq $brk_addr1 $Addr]} {
767
                dbg_uart_wr "BRK$i\_ADDR1" $brk_addr0
768
                return 1
769
            }
770
        }
771
    }
772
    return 1
773
}
774
 
775
#=============================================================================#
776
# IsHalted ()                                                                 #
777
#-----------------------------------------------------------------------------#
778
# Description: Check if the CPU is currently stopped or not.                  #
779
# Arguments  : None.                                                          #
780
# Result     : 0 if CPU is running, 1 if stopped.                             #
781
#=============================================================================#
782
proc IsHalted {} {
783
 
784
    # Check current target status
785
    set cpu_stat_val [dbg_uart_rd CPU_STAT]
786
    set halted       [expr 0x01 & $cpu_stat_val]
787
 
788
    return $halted
789
}
790
 
791
#=============================================================================#
792
# ClrStatus ()                                                                #
793
#-----------------------------------------------------------------------------#
794
# Description: Clear the status bit of the CPU_STAT register.                 #
795
# Arguments  : None.                                                          #
796
# Result     : 0 if error, 1 otherwise.                                       #
797
#=============================================================================#
798
proc ClrStatus {} {
799
 
800
    # Clear status
801
    dbg_uart_wr CPU_STAT  0xff
802
    dbg_uart_wr BRK0_STAT 0xff
803
    dbg_uart_wr BRK1_STAT 0xff
804
    dbg_uart_wr BRK2_STAT 0xff
805
    dbg_uart_wr BRK3_STAT 0xff
806
 
807
    return 1
808
}

powered by: WebSVN 2.1.0

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