# SPDX-License-Identifier: GPL-2.0-or-later

#  Copyright (C) ST-Ericsson SA 2011
#  Author : michel.jaouen@stericsson.com
#  U8500 target

proc mmu_off {} {
	set cp [arm mrc 15 0 1 0 0]
	set cp [expr {$cp & ~1}]
	arm mcr 15 0 1 0 0 $cp
}

proc mmu_on {} {
	set cp [arm mrc 15 0 1 0 0]
	set cp [expr {$cp | 1}]
	arm mcr 15 0 1 0 0 $cp
}

proc ocd_gdb_restart {target_id} {
    global _TARGETNAME_1
	global _SMP
    targets $_TARGETNAME_1
	if { $_SMP == 1 } {
	cortex_a smp off
	}
	rst_run
	halt
	if { $_SMP == 1 } {
	cortex_a smp on
	}
}

proc smp_reg {} {
	global _TARGETNAME_1
    global _TARGETNAME_2
    targets $_TARGETNAME_1
	echo "$_TARGETNAME_1"
	set pc1 [reg pc]
	set stck1 [reg sp_svc]
	targets $_TARGETNAME_2
	echo "$_TARGETNAME_1"
	set pc2 [reg pc]
	set stck2 [reg sp_svc]
}


proc u8500_tapenable {chip val} {
	echo "JTAG tap enable $chip"
}


proc pwrsts { } {
	global _CHIPNAME
	irscan $_CHIPNAME.jrc 0x3a
	drscan $_CHIPNAME.jrc 4 0
	set pwrsts [drscan $_CHIPNAME.jrc 16 0]
	echo "pwrsts ="$pwrsts
	set a9 [expr "0x$pwrsts & 0xc"]
	set ape [expr "0x$pwrsts & 0x3"]
	if {[string equal "0" $ape]} {
		echo "ape off"
	} else {
		echo "ape on"
	}
	echo "$a9"
	switch $a9 {
		4 {
			echo "A9 in retention"
		  }
		8 {
			echo "A9 100% DVFS"
		  }
		c {
			echo "A9 50% DVFS"
		}
	}
}

proc poll_pwrsts { } {
	global _CHIPNAME
	set result 1
	set i 0
	irscan $_CHIPNAME.jrc 0x3a
	drscan $_CHIPNAME.jrc 4 0
	set pwrsts [drscan $_CHIPNAME.jrc 16 0]
	set pwrsts [expr "0x$pwrsts & 0xc"]
	while {[string equal "4" $pwrsts] && $i<20} {
		irscan $_CHIPNAME.jrc 0x3a
		drscan $_CHIPNAME.jrc 4 0;
		set pwrsts [drscan $_CHIPNAME.jrc 16 0]
		set pwrsts [expr "0x$pwrsts & 0xc"]
		if {![string equal "4" $pwrsts]} {
			set result 1
		} else {
			set result 0
			sleep 200
			echo "loop $i"
		}
		incr i
	}
	return $result
}

proc halt_ { } {
	if {[poll_pwrsts]==1} {
		halt
	} else {
		echo "halt failed : target in retention"
	}
}


proc u8500_dapenable {chip} {
}

proc u8500_tapdisable {chip val} {
	echo "JTAG tap disable $chip"
}


proc enable_apetap {} {
	global _CHIPNAME
	global _TARGETNAME_2
    global _TARGETNAME_1
	poll off
	irscan $_CHIPNAME.jrc 0x3e
	drscan $_CHIPNAME.jrc 8 0xcf
	jtag tapenable $_CHIPNAME.dap
	irscan $_CHIPNAME.jrc 0x6
	drscan $_CHIPNAME.jrc 32 0
	irscan $_CHIPNAME.jrc 0x6
	drscan $_CHIPNAME.jrc 32 0
	set status [$_TARGETNAME_1 curstate]
    if {[string equal "unknown" $status]} {
	$_TARGETNAME_1 arp_examine
	cache_config l2x 0xa0412000 8
	}

	set status [$_TARGETNAME_2 curstate]
    if {[string equal "unknown" $status]} {
	$_TARGETNAME_2 arp_examine
	}
	}

tcl_port 5555
telnet_port 4444
gdb_port 3333

if { [info exists CHIPNAME] } {
global _CHIPNAME
    set _CHIPNAME $CHIPNAME
} else {
global _CHIPNAME
	set _CHIPNAME u8500
}

if { [info exists ENDIAN] } {
	set _ENDIAN $ENDIAN
} else {
 # this defaults to a bigendian
	set _ENDIAN little
}



# Subsidiary TAP: APE with scan chains for ARM Debug, EmbeddedICE-RT,
if { [info exists CPUTAPID] } {
   set _CPUTAPID $CPUTAPID
} else {
	set _CPUTAPID 0x4ba00477
}
jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0xe -irmask 0xf -expected-id $_CPUTAPID -disable
jtag configure $_CHIPNAME.cpu -event tap-enable \
	"u8500_dapenable $_CHIPNAME.cpu"
jtag configure $_CHIPNAME.cpu -event tap-disable \
	"u8500_tapdisable $_CHIPNAME.cpu 0xc0"


#CLTAPC TAP JRC equivalent
if { [info exists CLTAPC_ID] } {
   set _CLTAPC_ID $CLTAPC_ID
} else {
   set _CLTAPC_ID 0x22286041
}
jtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x6 -irmask 0xf -expected-id $_CLTAPC_ID -ignore-version


if { ![info exists TARGETNAME_1] } {
global _TARGETNAME_1
set _TARGETNAME_1 $_CHIPNAME.cpu1
} else {
global _TARGETNAME_1
set _TARGETNAME_1 $TARGETNAME_1
}

if { [info exists DAP_DBG1] } {
	set _DAP_DBG1 $DAP_DBG1
} else {
	set _DAP_DBG1 0x801A8000
}
if { [info exists DAP_DBG2] } {
	set _DAP_DBG2 $DAP_DBG2
} else {
	set _DAP_DBG2 0x801AA000
}

dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu

target create $_TARGETNAME_1 cortex_a -dap $_CHIPNAME.dap -dbgbase $_DAP_DBG1 -coreid 0 -rtos linux


if { ![info exists TARGETNAME_2] } {
global _TARGETNAME_2
set _TARGETNAME_2 $_CHIPNAME.cpu2
} else {
global _TARGETNAME_2
set _TARGETNAME_2 $TARGETNAME_2
}

target create $_TARGETNAME_2 cortex_a -dap $_CHIPNAME.dap -dbgbase $_DAP_DBG2 -coreid 1 -rtos linux


if {![info exists SMP]} {
global _SMP
set _SMP 1
} else {
global _SMP
set _SMP $SMP
}
global SMP
if { $_SMP == 1} {
target smp $_CHIPNAME.cpu2 $_CHIPNAME.cpu1
}




proc secsts1 { } {
	global _CHIPNAME
        irscan $_CHIPNAME.jrc 0x3a
		drscan $_CHIPNAME.jrc 4 4
	set secsts1 [drscan $_CHIPNAME.jrc 16 0]
	echo "secsts1 ="$secsts1
	set secsts1 [expr "0x$secsts1 & 0x4"]
	if {![string equal "4" $secsts1]} {
	echo "APE target secured"
        } else {
        echo "APE target not secured"
        }
}

proc att { } {
	global _CHIPNAME
	jtag arp_init
	irscan $_CHIPNAME.jrc 0x3a
	drscan $_CHIPNAME.jrc 4 4
	set secsts1 [drscan $_CHIPNAME.jrc 16 0]
	echo "secsts1 ="$secsts1
	set secsts1 [expr "0x$secsts1 & 0x4"]
	if {[string equal "4" $secsts1]} {
		if {[poll_pwrsts]==1} {
		enable_apetap
                } else {
		echo "target in retention"
		}
	} else {
		echo "target secured"
	}

}



proc rst_run { } {
	global _CHIPNAME
	global _TARGETNAME_2
	global _TARGETNAME_1
	set status [$_TARGETNAME_1 curstate]
	if {[string equal "halted" $status]} {
	resume
	targets $_TARGETNAME_1
	}
    set status [$_TARGETNAME_2 curstate]
	if {[string equal "halted" $status]} {
	resume
	targets $_TARGETNAME_2
	}
   	poll off
	jtag arp_init
	reset
	sleep 20
	irscan $_CHIPNAME.jrc 0x3a
	drscan $_CHIPNAME.jrc 4 4
	set secsts1 [drscan $_CHIPNAME.jrc 16 0]
	echo "secsts1 ="$secsts1
	set secsts1 [expr "0x$secsts1 & 0x4"]
	while {![string equal "4" $secsts1]} {
		irscan u8500.jrc 0x3a
		drscan u8500.jrc 4 4
		set secsts1 [drscan $_CHIPNAME.jrc 16 0]
		echo "secsts1 ="$secsts1
		set secsts1 [expr "0x$secsts1 & 0x4"]
	}
	echo "ape debugable"
	enable_apetap
	poll on
	targets $_TARGETNAME_1
	dap apsel 1
}

if {![info exists MAXSPEED]} {
global _MAXSPEED
set _MAXSPEED 15000
} else {
global _MAXSPEED
set _MAXSPEED $MAXSPEED
}
global _MAXSPEED
adapter speed $_MAXSPEED


gdb_breakpoint_override hard
set mem inaccessible-by-default-off

jtag_ntrst_delay 100
reset_config trst_and_srst combined
