This is an automated email from Gerrit.

Luis de Arquer ([email protected]) just uploaded a new patch set to 
Gerrit, which you can find at http://openocd.zylin.com/6124

-- gerrit

commit a7477408d6880f59abef5d8e5c307a5eb84eb7af
Author: Luis de Arquer <[email protected]>
Date:   Wed Mar 24 17:14:40 2021 +0100

    target/once: Initial support for On Chip Emulator (Power arch, e200 core)
    
    Basic support for debug control of the Power Architecture e200 core.
    All of the SPC56x/RPC56x devices from ST (and possibly MPC56x from NXP) 
should
    be compatible with this implementation, based on ST Application Note AN4035.
    
    The following functionality is provided:
     - Read/Write CPU registers
     - Read/Write arbitrary memory location (32-bit)
     - Execute single instruction
     - Load binary file to memory location
     - Execute code at specific memory location, until a breakpoint is reached
    
    Tested on ST SPC560D.
    
    binary.tcl is added as a dependency. It is taken from jimtcl. The full 
original
    license is added on the header, plus an SPDX meta tag, with GPL2 as extra 
choice
    
    Change-Id: Icaa8a5d38923f5768e64f00c62058fafe93ab6ed
    Signed-off-by: Luis de Arquer <[email protected]>

diff --git a/tcl/binary.tcl b/tcl/binary.tcl
new file mode 100644
index 0000000..fc1c7ca
--- /dev/null
+++ b/tcl/binary.tcl
@@ -0,0 +1,319 @@
+# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+#
+# Implements the 'binary scan' and 'binary format' commands.
+#
+# (c) 2010 Steve Bennett <[email protected]>
+#
+# Copyright 2005 Salvatore Sanfilippo <[email protected]>
+# Copyright 2005 Clemens Hintze <[email protected]>
+# Copyright 2005 patthoyts - Pat Thoyts <[email protected]>
+# Copyright 2008 oharboe - Øyvind Harboe - [email protected]
+# Copyright 2008 Andrew Lunn <[email protected]>
+# Copyright 2008 Duane Ellis <[email protected]>
+# Copyright 2008 Uwe Klein <[email protected]>
+# Copyright 2008 Steve Bennett <[email protected]>
+# Copyright 2009 Nico Coesel <[email protected]>
+# Copyright 2009 Zachary T Welch [email protected]
+# Copyright 2009 David Brownell
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above
+#    copyright notice, this list of conditions and the following
+#    disclaimer in the documentation and/or other materials
+#    provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# The views and conclusions contained in the software and documentation
+# are those of the authors and should not be interpreted as representing
+# official policies, either expressed or implied, of the Jim Tcl Project.
+
+
+package require pack
+package require regexp
+
+proc binary {cmd args} {
+       tailcall "binary $cmd" {*}$args
+}
+
+proc "binary format" {formatString args} {
+       set bitoffset 0
+       set result {}
+       # This RE is too unreliable...
+       foreach {conv t u n} [regexp -all -inline {([^[:space:]])(u)?([*0-9]*)} 
$formatString] {
+               switch -exact -- $t {
+                       a -
+                       A {
+                               set value [binary::nextarg args]
+                               set sn [string bytelength $value]
+                               if {$n ne "*"} {
+                                       if {$n eq ""} {
+                                               set n 1
+                                       }
+                                       if {$n > $sn} {
+                                               # Need to pad the string with 
spaces or nulls
+                                               append value [string repeat 
[dict get {A " " a \x00} $t] $($n - $sn)]
+                                       }
+                               } else {
+                                       set n $sn
+                               }
+                               if {$n} {
+                                       set bitoffset [pack result $value -str 
$(8 * $n) $bitoffset]
+                               }
+                       }
+                       x {
+                               if {$n eq "*"} {
+                                       return -code error {cannot use "*" in 
format string with "x"}
+                               }
+                               if {$n eq ""} {
+                                       set n 1
+                               }
+                               loop i 0 $n {
+                                       set bitoffset [pack result 0 -intbe 8 
$bitoffset]
+                               }
+                       }
+                       @ {
+                               if {$n eq ""} {
+                                       return -code error {missing count for 
"@" field specifier}
+                               }
+                               if {$n eq "*"} {
+                                       set bitoffset $(8 * [string bytelength 
$result])
+                               } else {
+                                       # May need to pad it out
+                                       set max [string bytelength $result]
+                                       append result [string repeat \x00 $($n 
- $max)]
+                                       set bitoffset $(8 * $n)
+                               }
+                       }
+                       X {
+                               if {$n eq "*"} {
+                                       set bitoffset 0
+                               } elseif {$n eq ""} {
+                                       incr bitoffset -8
+                               } else {
+                                       incr bitoffset $($n * -8)
+                               }
+                               if {$bitoffset < 0} {
+                                       set bitoffset 0
+                               }
+                       }
+                       default {
+                               if {![info exists ::binary::scalarinfo($t)]} {
+                                       return -code error "bad field specifier 
\"$t\""
+                               }
+
+                               # A scalar (integer or float) type
+                               lassign $::binary::scalarinfo($t) type convtype 
size prefix
+                               set value [binary::nextarg args]
+
+                               if {$type in {bin hex}} {
+                                       set value [split $value {}]
+                               }
+                               set vn [llength $value]
+                               if {$n eq "*"} {
+                                       set n $vn
+                               } elseif {$n eq ""} {
+                                       set n 1
+                                       set value [list $value]
+                               } elseif {$vn < $n} {
+                                       if {$type in {bin hex}} {
+                                               # Need to pad the list with 
zeros
+                                               lappend value {*}[lrepeat $($n 
- $vn) 0]
+                                       } else {
+                                               return -code error "number of 
elements in list does not match count"
+                                       }
+                               } elseif {$vn > $n} {
+                                       # Need to truncate the list
+                                       set value [lrange $value 0 $n-1]
+                               }
+
+                               set convtype -$::binary::convtype($convtype)
+
+                               foreach v $value {
+                                       set bitoffset [pack result $prefix$v 
$convtype $size $bitoffset]
+                               }
+                               # Now pad out with zeros to the end of the 
current byte
+                               if {$bitoffset % 8} {
+                                       set bitoffset [pack result 0 $convtype 
$(8 - $bitoffset % 8) $bitoffset]
+                               }
+                       }
+               }
+       }
+       return $result
+}
+
+proc "binary scan" {value formatString {args varName}} {
+       # Pops the next arg from the front of the list and returns it.
+       # Throws an error if no more args
+       set bitoffset 0
+       set count 0
+       # This RE is too unreliable...
+       foreach {conv t u n} [regexp -all -inline {([^[:space:]])(u)?([*0-9]*)} 
$formatString] {
+               set rembytes $([string bytelength $value] - $bitoffset / 8)
+               switch -exact -- $t {
+                       a -
+                       A {
+                               if {$n eq "*"} {
+                                       set n $rembytes
+                               } elseif {$n eq ""} {
+                                       set n 1
+                               }
+                               if {$n > $rembytes} {
+                                       break
+                               }
+
+                               set var [binary::nextarg varName]
+
+                               set result [unpack $value -str $bitoffset $($n 
* 8)]
+                               incr bitoffset $([string bytelength $result] * 
8)
+                               if {$t eq "A"} {
+                                       set result [string trimright $result]
+                               }
+                       }
+                       x {
+                               # Skip bytes
+                               if {$n eq "*"} {
+                                       set n $rembytes
+                               } elseif {$n eq ""} {
+                                       set n 1
+                               }
+                               if {$n > $rembytes} {
+                                       set n $rembytes
+                               }
+                               incr bitoffset $($n * 8)
+                               continue
+                       }
+                       X {
+                               # Back up bytes
+                               if {$n eq "*"} {
+                                       set bitoffset 0
+                                       continue
+                               }
+                               if {$n eq ""} {
+                                       set n 1
+                               }
+                               if {$n * 8 > $bitoffset} {
+                                       set bitoffset 0
+                                       continue
+                               }
+                               incr bitoffset -$($n * 8)
+                               continue
+                       }
+                       @ {
+                               if {$n eq ""} {
+                                       return -code error {missing count for 
"@" field specifier}
+                               }
+                               if {$n eq "*" || $n > $rembytes + $bitoffset / 
8} {
+                                       incr bitoffset $($rembytes * 8)
+                               } elseif {$n < 0} {
+                                       set bitoffset 0
+                               } else {
+                                       set bitoffset $($n * 8)
+                               }
+                               continue
+                       }
+                       default {
+                               if {![info exists ::binary::scalarinfo($t)]} {
+                                       return -code error "bad field specifier 
\"$t\""
+                               }
+                               # A scalar (integer or float) type
+                               lassign $::binary::scalarinfo($t) type convtype 
size prefix
+                               set var [binary::nextarg varName]
+
+                               if {$n eq "*"} {
+                                       set n $($rembytes * 8 / $size)
+                               } else {
+                                       if {$n eq ""} {
+                                               set n 1
+                                       }
+                               }
+                               if {$n * $size > $rembytes * 8} {
+                                       break
+                               }
+
+                               if {$type in {hex bin}} {
+                                       set u u
+                               }
+                               set convtype -$u$::binary::convtype($convtype)
+
+                               set result {}
+                               loop i 0 $n {
+                                       set v [unpack $value $convtype 
$bitoffset $size]
+                                       if {$type in {bin hex}} {
+                                               append result [lindex {0 1 2 3 
4 5 6 7 8 9 a b c d e f} $v]
+                                       } else {
+                                               lappend result $v
+                                       }
+                                       incr bitoffset $size
+                               }
+                               # Now skip to the end of the current byte
+                               if {$bitoffset % 8} {
+                                       incr bitoffset $(8 - ($bitoffset % 8))
+                               }
+                       }
+               }
+               uplevel 1 [list set $var $result]
+               incr count
+       }
+       return $count
+}
+
+# Pops the next arg from the front of the list and returns it.
+# Throws an error if no more args
+proc binary::nextarg {&arglist} {
+       if {[llength $arglist] == 0} {
+               return -level 2 -code error "not enough arguments for all 
format specifiers"
+       }
+       set arglist [lassign $arglist arg]
+       return $arg
+}
+
+set binary::scalarinfo {
+       c {int be 8}
+       s {int le 16}
+       t {int host 16}
+       S {int be 16}
+       i {int le 32}
+       I {int be 32}
+       n {int host 32}
+       w {int le 64}
+       W {int be 64}
+       m {int host 64}
+       h {hex le 4 0x}
+       H {hex be 4 0x}
+       b {bin le 1}
+       B {bin be 1}
+       r {float fle 32}
+       R {float fbe 32}
+       f {float fhost 32}
+       q {float fle 64}
+       Q {float fbe 64}
+       d {float fhost 64}
+}
+set binary::convtype {
+       be intbe
+       le intle
+       fbe floatbe
+       fle floatle
+}
+if {$::tcl_platform(byteOrder) eq "bigEndian"} {
+       array set binary::convtype {host intbe fhost floatbe}
+} else {
+       array set binary::convtype {host intle fhost floatle}
+}
diff --git a/tcl/target/once.cfg b/tcl/target/once.cfg
new file mode 100644
index 0000000..e2eec5e
--- /dev/null
+++ b/tcl/target/once.cfg
@@ -0,0 +1,273 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# e200z0 OnCE (On Chip Emulator)
+#
+# Copyright (c) 2021, Hsin Chong Machinery Works Co., Ltd
+# Copyright (c) 2021, Inertim Research, SL
+# [email protected]
+#
+#
+# The On-Chip Emulation is part of Nexus/JTAG specification.
+# Implemented following the ST Application Note AN4035
+#
+# Nexus/JTAG Flash programming supports the following products:
+#  SPC563Mxx
+#  SPC564Axx
+#  SPC56APxx
+#  SPC560Dxx
+#  SPC560Bxx
+#  SPC564Bxx
+#  SPC560Cxx
+#  SPC560Pxx
+#  SPC56ECxx
+#  SPC56ELxx
+#  RPC56ELxx
+#  RPC560Bxx
+#  RPC564Bxx
+#  RPC56APxx
+#  RPC564Axx
+#
+
+
+source [find binary.tcl]
+
+
+proc once_read_osr {once} {
+
+       set osr 0x[irscan $once 0x011]
+       return $osr
+}
+
+
+proc once_read_jtag_id {once} {
+
+       irscan $once 0x002
+       set once_id 0x[drscan $once 32 0x00000000]
+       return $once_id
+}
+
+
+proc once_read_dbsr {once} {
+
+       irscan $once 0x230
+       set dbsr 0x[drscan $once 32 0x00000000]
+       return $dbsr
+}
+
+
+proc once_read_cpuscr {once} {
+
+       irscan $once 0x210
+       set cpuscr [drscan $once 32 0x00000000 32 0x00000000 32 0x00000000 32 
0x00000000 32 0x00000000 32 0x00000000]
+       return $cpuscr
+}
+
+
+proc once_enter_debug_mode {once} {
+
+       # First we need to enter debug mode, then enable external debug mode.
+
+       # 1- Enter debug mode while holding reset
+       jtag_reset 0 1
+
+       irscan $once 0x012
+       set ocr 0x[drscan $once 32 0x00000005]
+
+       jtag_reset 0 0
+
+       # TODO: We can use this read for checking (osr == 0x209)
+       #set osr [once_read_osr $once]
+       #echo "OSR = $osr"
+
+       irscan $once 0x012
+       set ocr 0x[drscan $once 32 0x00000006]
+
+       # 2- Enable external debug mode
+       # Write DBCR0 for enabling external debug
+       irscan $once 0x031
+       drscan $once 32 0x80000000
+
+       # Clear all DBSR flags
+       irscan $once 0x030
+       drscan $once 32 0xFFFFFFFF
+}
+
+
+proc once_read_pc {once} {
+
+       # Read CPUSCR register chain -> [ WBBRL WBBRH MSR PC IR CTL ]
+       irscan $once 0x210
+       set cpuscr [drscan $once 32 0x00000000 32 0x00000000 32 0x00000000 32 
0x00000000 32 0x00000000 32 0x00000000]
+
+       # Save PC subregister
+       set pc 0x[lindex $cpuscr 3]
+
+       return $pc
+}
+
+
+proc once_read_wbbr {once} {
+
+       # Read CPUSCR register chain -> [ WBBRL WBBRH MSR PC IR CTL ]
+       irscan $once 0x210
+       set cpuscr [drscan $once 32 0x00000000 32 0x00000000 32 0x00000000 32 
0x00000000 32 0x00000000 32 0x00000000]
+
+       # Save WBBRL subregister
+       set wbbr 0x[lindex $cpuscr 0]
+
+       return $wbbr
+}
+
+
+# Single step with WBBR.
+# WBBR is used to pass operand information to/from CPU
+proc once_single_step_wbbr {once instruction wbbr} {
+
+       # Read CPUSCR register chain -> [ WBBRL WBBRH MSR PC IR CTL ]
+       irscan $once 0x210
+       set cpuscr [drscan $once 32 0x00000000 32 0x00000000 32 0x00000000 32 
0x00000000 32 0x00000000 32 0x00000000]
+
+       # Save CTL subregister
+       set ctl 0x[lindex $cpuscr 5]
+
+       set ctl [expr $ctl & 0xFFFF0000]
+       set ctl [expr $ctl | 0x00000402]    ;# FFRA=1 (Use wbbr), IRSTAT8=1 
(VLE inst)
+       set ctl [format 0x%08x $ctl]
+
+       # Write CPUSCR
+       irscan $once 0x010
+       drscan $once 32 $wbbr 32 0x00000000 32 0x00000000 32 0x00000008 32 
$instruction 32 $ctl
+
+       # GO command
+       irscan $once 0x111
+       drscan $once 32 0x00000000
+}
+
+
+# Single step without WBBR
+proc once_single_step {once instruction} {
+
+       # Read CPUSCR register chain -> [ WBBRL WBBRH MSR PC IR CTL ]
+       irscan $once 0x210
+       set cpuscr [drscan $once 32 0x00000000 32 0x00000000 32 0x00000000 32 
0x00000000 32 0x00000000 32 0x00000000]
+
+       # Save CTL subregister
+       set ctl 0x[lindex $cpuscr 5]
+
+       set ctl [expr $ctl & 0xFFFF0000]
+       set ctl [expr $ctl | 0x00000002]    ;# FFRA=0 (Don't use wbbr), 
IRSTAT8=1 (VLE inst)
+       set ctl [format 0x%08x $ctl]
+
+       # Write CPUSCR
+       irscan $once 0x010
+       drscan $once 32 0x00000000 32 0x00000000 32 0x00000000 32 0x00000008 32 
$instruction 32 $ctl
+
+       # GO command
+       irscan $once 0x111
+       drscan $once 32 0x00000000
+}
+
+
+proc once_read32 {once address} {
+
+       once_single_step_wbbr $once 0x501F0000 $address
+
+       # Read CPUSCR
+       irscan $once 0x210
+       set cpuscr [drscan $once 32 0x00000000 32 0x00000000 32 0x00000000 32 
0x00000000 32 0x00000000 32 0x00000000]
+
+       set value 0x[lindex $cpuscr 0]
+       return $value
+}
+
+proc once_write32 {once address value} {
+
+       # Write $value into R1
+       once_single_step_wbbr $once 0x1BE1D000 $value
+
+       # Write R1 into address
+       once_single_step_wbbr $once 0x543F0000 $address
+}
+
+
+proc once_read_gpr {once gpr} {
+
+       # ori gpr ^ 0 -> gpr and wwbr
+       set shifted_gpr_s [expr $gpr << 21]
+       set shifted_gpr_a [expr $gpr << 16]
+       set inst 0x1800D000
+       set inst [format 0x%08X [expr $inst | $shifted_gpr_s]]
+       set inst [format 0x%08X [expr $inst | $shifted_gpr_a]]
+
+       once_single_step $once $inst
+
+       set value [once_read_wbbr $once]
+       return $value
+}
+
+
+proc once_write_gpr {once gpr value} {
+
+       # ori value ^ 0 -> gpr
+       set shifted_gpr [expr $gpr << 16]
+       set inst 0x1800D000
+       set inst [format 0x%08X [expr $inst | $shifted_gpr]]
+
+       once_single_step_wbbr $once $inst $value
+
+}
+
+
+# Load binary file to SRAM
+# If the binary is going to be executed, it should end with 32 bit zeroes
+# (this creates a breakpoint)
+proc once_load_bin {once address filename} {
+
+       set infile [open $filename r]
+
+       set bytes [read $infile 4]
+       while { $bytes ne ""} {
+               set ret [binary scan $bytes Iu s]
+               if { $ret == 0 } {
+                       puts "File size is not multiple of 4"
+                       exit
+               }
+               set s [format 0x%08X $s]
+               puts "Block: $s"
+
+               once_write32 $once $address $s
+
+               set address [expr 0x04 + $address]
+               set address [format 0x%08X $address]
+               set bytes [read $infile 4]
+       }
+}
+
+
+# Run a previously loaded binary on @address
+proc once_run {once address} {
+
+       # Read CPUSCR register chain -> [ WBBRL WBBRH MSR PC IR CTL ]
+       irscan $once 0x210
+       set cpuscr [drscan $once 32 0x00000000 32 0x00000000 32 0x00000000 32 
0x00000000 32 0x00000000 32 0x00000000]
+
+       # Save CTL subregister
+       set ctl 0x[lindex $cpuscr 5]
+
+       set ctl [expr $ctl & 0xFFFF0000]
+       set ctl [expr $ctl | 0x00000002]    ;# FFRA=0 (Don't use wbbr), 
IRSTAT8=1 (VLE inst)
+       set ctl [format 0x%08X $ctl]
+
+       set pc [expr $address - 0x02]
+       set pc [format 0x%08X $pc]
+       #puts "pc = $pc"
+
+       # Write CPUSCR
+       set instruction 0x60000000   ;# nop
+       irscan $once 0x010
+       drscan $once 32 0x00000000 32 0x00000000 32 0x00000000 32 $pc 32 
$instruction 32 $ctl
+
+       # GO command + Leave debug mode
+       irscan $once 0x191
+       drscan $once 32 0x00000000
+}

-- 


_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to