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 77

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

powered by: WebSVN 2.1.0

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