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

#
# Nordic nRF52, nRF53 and nRF91 CTRL-AP handling
#

if { [using_hla] } {
	echo ""
	echo "nRF device has a CTRL-AP dedicated to recover the device from AP lock."
	echo "A high level adapter (like a ST-Link) you are currently using cannot access"
	echo "the CTRL-AP so 'nrfxx_recover' command will not work."
	echo "Do not enable UICR APPROTECT."
	echo ""
} else {

	# Test if debug/MEM-AP is locked by UICR APPROTECT
	proc _nrf_check_ap_lock { ctrl_ap_num unlocked_value } {
		set target [target current]
		set dap [$target cget -dap]
		set err [catch {set APPROTECTSTATUS [$dap apreg $ctrl_ap_num 0xc]}]
		if {$err == 0 && $APPROTECTSTATUS < $unlocked_value} {
			echo ""
			echo "****** WARNING ******"
			echo "\[$target\] device has AP lock engaged (see UICR APPROTECT register)."
			echo "Debug access is denied."
			echo "Use 'nrfxx_recover' to erase and unlock the device."
			echo ""
			poll off
			return 1
		}
		return 0
	}

	# Mass erase and unlock the device using proprietary nRF CTRL-AP
	proc _nrf_ctrl_ap_recover { ctrl_ap_num {is_cpunet 0} } {
		set target [target current]
		set dap [$target cget -dap]

		set IDR [$dap apreg $ctrl_ap_num 0xfc]
		if {$IDR != 0x12880000} {
			echo "Error: Cannot access nRF CTRL-AP!"
			return
		}

		poll off

		# Reset and trigger ERASEALL task
		$dap apreg $ctrl_ap_num 4 0
		$dap apreg $ctrl_ap_num 4 1

		for {set i 0} {1} {incr i} {
			set ERASEALLSTATUS [$dap apreg $ctrl_ap_num 8]
			if {$ERASEALLSTATUS == 0} {
				echo "\[$target\] device has been successfully erased and unlocked."
				break
			}
			if {$i == 0} {
				echo "Waiting for chip erase..."
			}
			if {$i >= 150} {
				echo "Error: \[$target\] recovery failed."
				break
			}
			sleep 100
		}

		# Assert reset
		$dap apreg $ctrl_ap_num 0 1

		# Deassert reset
		$dap apreg $ctrl_ap_num 0 0

		# Reset ERASEALL task
		$dap apreg $ctrl_ap_num 4 0

		if { $is_cpunet } {
			reset init
		} else {
			sleep 100
			$target arp_examine
			poll on
		}
	}

	lappend _telnet_autocomplete_skip _nrf_check_ap_lock _nrf_ctrl_ap_recover
}
