#
# Voipac VPACLink
#
# http://voipac.com/27M-JTG-000
#

telnet_port     4444
gdb_port        3333

#interface ft2232
#ft2232_device_desc "VPACLink"
#ft2232_layout oocdlink
#ft2232_vid_pid 0x0403 0x6010
#adapter_khz 100

interface ftdi
ftdi_device_desc "Dual RS232-HS"
ftdi_vid_pid 0x0403 0x6010
ftdi_layout_init 0x0c08 0x0f1b
ftdi_layout_signal nTRST -data 0x0100 -noe 0x0400
ftdi_layout_signal nSRST -data 0x0200 -noe 0x0800
adapter_khz 1000

#reset_config none

# Freescale i.MX51
if { [info exists CHIPNAME] } {
   set  _CHIPNAME $CHIPNAME
} else {
   set  _CHIPNAME imx51
}

# CoreSight Debug Access Port
if { [info exists DAP_TAPID ] } {
   set _DAP_TAPID $DAP_TAPID
} else {
   set _DAP_TAPID 0x1ba00477
}

jtag newtap $_CHIPNAME DAP -irlen 4 -ircapture 0x1 -irmask 0xf \
        -expected-id $_DAP_TAPID

# SDMA / no IDCODE
jtag newtap $_CHIPNAME SDMA -irlen 4 -ircapture 0x0 -irmask 0xf

# SJC
if { [info exists SJC_TAPID ] } {
   set _SJC_TAPID SJC_TAPID
} else {
   set _SJC_TAPID 0x0190c01d
}

jtag newtap $_CHIPNAME SJC -irlen 5 -ircapture 0x1 -irmask 0x1f \
        -expected-id $_SJC_TAPID -ignore-version


# GDB target:  Cortex-A, using DAP
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME cortex_a -chain-position $_CHIPNAME.DAP -dbgbase 0x60008000

# some TCK tycles are required to activate the DEBUG power domain
jtag configure $_CHIPNAME.SJC -event post-reset "runtest 100"

# have the DAP "always" be active
jtag configure $_CHIPNAME.SJC -event setup "jtag tapenable $_CHIPNAME.DAP"

nand device 29F4G08ABADA mx5 $_TARGETNAME hwecc biswap

init

proc imx51_dbginit {target} {
     # General Cortex A debug initialisation
     cortex_a dbginit
}

proc load_uboot {} {
	halt
	arm core_state arm
        load_image /home/theosoft/imx-build/u-boot/u-boot.bin 0x97800000
#	sdhc 0 0x97800000 0x400 0x4d000
	step 0x97800000
}

proc n_steps {steps} {
	for {set a 0} {$a <= $steps} {incr a 1} { 
		step
	}
}
# Debug Status and Control register
proc dscr {} {
	echo [format 0x%08x [arm mrc 14 0 0 1 0]]
}


# MMU disable
proc mmud {} {
	reg cpsr 0x1d3
	echo [format 0x%08x [arm mrc 15 0 1 0 0]]
	arm mcr 15 0 1 0 0 [expr {[arm mrc 15 0 1 0 0] & 0xffffcc7a}]
	step
}

proc wdt_disable {} {
	# disable WDT
	mwh 0x73f98000 0x3
}

# This program resets the regs to the address 0x17800000
#   making the incorrect assumption that the start of the code
#   is located there.
# It sets up the cpsr so we can run the code properly.
proc clear_regs {} {
     puts "clear_regs begin"
     reg r1 0
     reg r2 0
     reg r3 0
     reg r4 0
     reg r5 0
     reg r6 0
     reg r7 0
     reg r8 0
     reg r9 0
     reg r10 0
     reg r11 0
     reg r12 0

     # assume our executable is at 0x17800000. otherwise the
     #   user must manually set the value after a reset.
     reg pc  0x97801000

     # shamelessly stolen from the samsung configuration
     #   this fixes problems executing loaded code.
     reg cpsr 0x1d3
     arm mcr 15 0 15 2 4 0x70000013

     puts "clear_regs end"
}

# MMU enable
proc mmue {} {
	reg cpsr 0x1d3
	echo [format 0x%08x [arm mrc 15 0 1 0 0]]
	arm mcr 15 0 1 0 0 [expr {[arm mrc 15 0 1 0 0] | 0x00000005}]
	step
}

# prepare memory access for registers AXI and IP
proc pm {} {
	halt	
	mmud
	dap apsel 1
}

# erase page 0 to enable bootstrap
proc bt_enable {} {
	pm
	#set high Address 
	mww 0xcfff1e04 0x0 
        mww 0xcfff1e24 0x0
	#set ram to block 0 and NFC reset
	mww 0xcfff1e34 0x0
	#set autocmd autoprogram
	mww 0xcfff1e00 0x0070D060
	# do auto_erase
	mww 0xcfff1e40 0x20
	sleep 500	
    	mdw 0xcfff1e3c
}


# program flash with autowrite NFC option
# number in  Range 0x00000000 - 0x000007ff --> Page 0
# number in  Range 0x00010000 - 0x000107ff --> Page 1

proc pfpart {p_start p_stop} {
# todo 
# NAND's CMD setzen 0x80 0x10
# RAM füllen
# Addr0 und Addr8 setzen
# Auto erase ??
# RAM Quelle setzen
# Autowrite setzen
# register read and set bits ??

#	set p_start 0x00030000
#	set p_stop 0x000030800
    
	set start_len [string length $p_start]
	set stop_len [string length $p_stop]

	if  [expr $start_len != 12] {break}
	if [expr $stop_len != 12] {break}
	scan $p_start %x start_int
	scan $p_stop %x stop_int
	if [expr $stop_int < $start_int] {break}
  
	#convert real address to flash address
 	set block_len [expr $stop_int - $start_int]

	set start_flash_int [expr $start_int << 1]
   	set stop_flash_int [expr $stop_int << 1]

   	set addr0_start_shift_h [expr (($start_int & 0x00fffff800) << 5)]
 	set addr0_stop_shift_h [expr (($stop_int & 0x00fffff800) << 5)]
   	set addr0_start_shift_l [expr ($start_int & 0x00000007ff) ]
 	set addr0_stop_shift_l [expr ($stop_int & 0x00000007ff)]

   	set addr0_start [expr (($addr0_start_shift_h | $addr0_start_shift_l ) & 0x00ffff07ff)]
 	set addr0_stop [expr (($addr0_stop_shift_h | $addr0_stop_shift_l) & 0x00ffff07ff)]
  	set addr8_start [expr (($start_flash_int & 0xff00000000) >> 32)]
	set addr8_stop [expr (($stop_flash_int & 0xff00000000) >> 32)]
	#block overlap not supported till now
	if [expr $addr8_start != $addr8_stop] {break}

    	echo  [format "0x%.8X" $addr0_start]
    	echo  [format "0x%.8X" $addr0_stop]
    	echo  [format "0x%.8X" $addr8_start]
    	echo  [format "0x%.8X" $addr8_stop]
    	echo  [format "0x%.8X" $block_len]

	pm
	#set high Address 
#	mww 0xcfff1e04 $addr0_start 
#       mww 0xcfff1e24 $addr8_start
	#Helps, but don't now why			
	reg pc 0
	#set ram to block 0 and NFC reset
#	mww 0xcfff1e34 0x0
	#set autocmd autoprogram
#	mww 0xcfff1e00 0x00001080
	load_image one_page.hex 0xcfff0000 0x800
	#write autoprog cmd
#	mww 0xcfff1e40 0x40
}

# dump flash with autoread NFC option
# number in  Range 0x00000000 - 0x000007ff --> Page 0
# number in  Range 0x00010000 - 0x000107ff --> Page 1

proc dfpart {start stop} {
#	set start 0x1ff70000
#	set stop 0x1ff80000
    
	set start_len [string length $start]
	set stop_len [string length $stop]

	if  [expr $start_len != 10] {break}
	if [expr $stop_len != 10] {break}
	scan $start %x start_int
	scan $stop %x stop_int
	if [expr $stop_int < $start_int] {break}
    
	#convert real address to flash address
	set start_flash_int [expr $start_int << 5]
    	set stop_flash_int [expr $stop_int << 5]
   	set block_len [expr $stop_int - $start_int]
    	set addr0_start [expr ($start_flash_int & 0x00FFFF0000)]
    	set addr8_start [expr (($start_flash_int & 0xff00000000) >> 32)]
    	set addr0_stop [expr ($stop_flash_int & 0x00ffff0000)]
   	set addr8_stop [expr (($stop_flash_int & 0xff00000000) >> 32)]
	#block overlap not supported till now
	if [expr $addr8_start != $addr8_stop] {break}

    
    	echo  [format "0x%.12X" $addr0_start]
    	echo  [format "0x%.12X" $addr8_start]
    	echo  [format "0x%.12X" $addr0_stop]
    	echo  [format "0x%.12X" $addr8_stop]
    	echo  [format "0x%.12X" $block_len]
	#prepare memory
	pm
	#set high Address 
        mww 0xcfff1e24 $addr8_start
#	set b $start_int
	for {set a $addr0_start} {$a <= $addr0_stop} {incr a 0x10000} { 
		
		#Helps, but don't now why			
		reg pc 0
		#set ram to block 0 and NFC reset
		mww 0xcfff1e34 0x4
		#set adress to page begin
		mww 0xcfff1e04 $a 
		#autoread
		mww 0xcfff1e40 0x80
#		sleep 500
		set fn1 [format "0x%.8X" $start_int]
		set fn2 [format "_0x%.8X" [expr $start_int + 0x7ff]]
		dump_image dump$fn1$fn2.hex 0xcfff0000 0x800
		echo $fn1$fn2
		set start_int [expr $start_int + 0x800]
	}
	echo "Finished partial flash dump"
}

# dump flash with autoread NFC option very slow !!
# number in  Range 0x00000000 - 0x000007ff --> Page 0
# number in  Range 0x00010000 - 0x000107ff --> Page 1

proc dffull {} {
	set flash_Start_Addr 0x00000000
	set flash_End_Addr 0x07ffffff
	dfpart {$flash_Start_Addr $flash_End_Addr}
	set flash_Start_Addr 0x08000000
	set flash_End_Addr 0x0fffffff
	dfpart {$flash_Start_Addr $flash_End_Addr}
	set flash_Start_Addr 0x10000000
	set flash_End_Addr 0x17ffffff
	dfpart {$flash_Start_Addr $flash_End_Addr}
	set flash_Start_Addr 0x18000000
	set flash_End_Addr 0x1fffffff
	dfpart {$flash_Start_Addr $flash_End_Addr}
}

proc dasm {addr {length 8}} {
	arm disassemble $addr $length
}

proc reset_halt {} {
	adapter_khz 100
	halt
	bp 0 4 hw
	resume
	jtag_reset 0 1
	sleep 500
	jtag_reset 0 0
}

# Slow speed to be sure it will work
$_TARGETNAME configure -event reset-start { adapter_khz 100 }

$_TARGETNAME configure -event reset-end { jtag_rclk 1000 }

$_TARGETNAME configure -event reset-assert-post "imx51_dbginit $_TARGETNAME"

proc init_l2cc {} {
	# enable L1NEON bit
	arm mcr 15 0 1 0 1 [expr {[arm mrc 15 0 1 0 1] | 0x20}]
	# explicitly disable L2 cache
	arm mcr 15 0 1 0 1 [expr {[arm mrc 15 0 1 0 1] & ~0x2}]
	# reconfigure L2 cache aux control reg
	arm mcr 15 1 9 0 2 0x01C000C4
}


#proc boot {{FILE barebox.bin}} {
#	halt
#	arm core_state arm
#	load_image $FILE 0x90000000
#	step 0x90008000
#	resume
#}

#proc vmx51_init {} {
#	echo "Configuring VMX51..."
#
#	halt
#	# set ARM state
#	arm core_state arm
#
#	# set SU mode, disable MMU
#	arm mcr 15 0 1 0 0 0x00050078
#	reg cpsr 0x1d3
#
#	adapter_khz 1000
#
#	init_l2cc
#
#	init_aips
#
#	# disable WDT
#	mwh 0x73f98000 0x30
#
#	# init DDR2
#	init_ddr2
#
#	echo "Initialisation completed..."
#}

JTAG & Serial definitions:

Soldering looks bad, but i had to try a lot of combinations :)

For orientation: the left blue is pin 1 and the lower row ends with 10

The upper row starts with 11 and ends with 19. Pin 11 is above pin 2.

T-Hub PinDescription20Pin ARM Jtag
1 Gnd2,4,6,8,10,12,14,16,18,20
2Vref 1.8 Volt !1
3nreset ??15 may be not needed
4TDO13
5TDI5
6TCK9
7RTCK ??11 may be not needed
8TMS7
9nc
10nc
11nc
12Gnd
13RxD 3.3 Volt
14TxD 3.3 Volt
15nc
16nc
17nc
18nc
19nc