# # Copyright (C) 2011 by Karl Kurbjun # Copyright (C) 2009 by David Brownell # # Utilities for TI ICEpick-C/D used in most TI SoCs # Details about the ICEPick are available in the the TRM for each SoC # and http://processors.wiki.ti.com/index.php/ICEPICK # create "constants" proc CONST { key } { array set constant { # define ICEPick instructions IR_BYPASS 0x00 IR_ROUTER 0x02 IR_CONNECT 0x07 IF_BYPASS 0x3F } return $constant($key) } # Instruction to connect to the icepick module proc icepick_c_connect {jrc} { # Send CONNECT instruction in IR state irscan $jrc [CONST IR_CONNECT] -endstate IRPAUSE # Send write and connect key drscan $jrc 8 0x89 -endstate DRPAUSE } # Instruction to disconnect to the icepick module proc icepick_c_disconnect {jrc} { # Send CONNECT instruction in IR state irscan $jrc [CONST IR_CONNECT] -endstate IRPAUSE # Send write and connect key drscan $jrc 8 0x86 -endstate DRPAUSE } # # icepick_c_router: # this function is for sending router commands # arguments are: # jrc: TAP name for the ICEpick # rw: read/write (0 for read, 1 for write) # block: icepick or DAP # register: which register to read/write # payload: value to read/write # this function is for sending router commands # proc icepick_c_router {jrc rw block register payload} { set new_dr_value \ [expr ( ($rw & 0x1) << 31) | ( ($block & 0x7) << 28) | \ ( ($register & 0xF) << 24) | ( $payload & 0xFFFFFF ) ] # echo "\tNew router value:\t0x[format %x $new_dr_value]" # select router irscan $jrc [CONST IR_ROUTER] -endstate IRPAUSE # ROUTER instructions are 32 bits wide set old_dr_value [drscan $jrc 32 $new_dr_value -endstate DRPAUSE] } # Configure the icepick control register proc icepick_c_setup {jrc} { # send a router write, block is 0, register is 1, value is 0x2100 icepick_c_router $jrc 1 0x0 0x1 0x001000 } # jrc == TAP name for the ICEpick # port == a port number, 0..15 proc icepick_c_tapenable {jrc port} { # First CONNECT to the ICEPick # echo "Connecting to ICEPick" icepick_c_connect $jrc # echo "Configuring the ICEpick" icepick_c_setup $jrc # NOTE: it's important not to enter RUN/IDLE state until # done sending these instructions and data to the ICEpick. # And never to enter RESET, which will disable the TAPs. # first enable power and clock for TAP icepick_c_router $jrc 1 0x2 $port 0x100048 # TRM states that the register should be read back here, skipped for now # enable debug "default" mode icepick_c_router $jrc 1 0x2 $port 0x102048 # TRM states that debug enable and debug mode should be read back and # confirmed - skipped for now # Finally select the tap icepick_c_router $jrc 1 0x2 $port 0x102148 # Enter the bypass state irscan $jrc [CONST IR_BYPASS] -endstate RUN/IDLE runtest 10 } # jrc == TAP name for the ICEpick # port == a port number, 0..15 # Follow the sequence described in # http://processors.wiki.ti.com/images/f/f6/Router_Scan_Sequence-ICEpick-D.pdf proc icepick_d_tapenable {jrc port} { # First CONNECT to the ICEPick icepick_c_connect $jrc icepick_c_setup $jrc # Select the port icepick_c_router $jrc 1 0x2 $port 0x2108 # Set 4 bit core ID to the Cortex-A irscan $jrc [CONST IR_ROUTER] -endstate IRPAUSE drscan $jrc 32 0xe0002008 -endstate DRPAUSE # Enter the bypass state irscan $jrc [CONST IF_BYPASS] -endstate RUN/IDLE runtest 10 } # This function uses the ICEPick to send a warm system reset proc icepick_c_wreset {jrc} { # send a router write, block is 0, register is 1, value is 0x2100 icepick_c_router $jrc 1 0x0 0x1 0x002101 }