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 2

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

powered by: WebSVN 2.1.0

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