# HG changeset patch # User Mychaela Falconia # Date 1561590266 0 # Node ID 66879ce73b3ef8bb4fc25d1719a90436ba996037 # Parent 240221552ecf9eca8f5a1949f9f2a0bfb259ad03 doc/Calypso-OpenOCD-Howto article written diff -r 240221552ecf -r 66879ce73b3e doc/Calypso-OpenOCD-Howto --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/Calypso-OpenOCD-Howto Wed Jun 26 23:04:26 2019 +0000 @@ -0,0 +1,191 @@ +Using OpenOCD to operate on Calypso JTAG: proof of concept +========================================================== + +We have a proof-of-concept OpenOCD configuration for talking to Calypso JTAG +based on the theoretical findings described in the Calypso-JTAG-notes document +in the freecalypso-docs repository; the present document describes how one can +practically use OpenOCD on an FCDEV3B target. + +Choice of JTAG adapter hardware +=============================== + +The PoC presented here uses an off-the-shelf unbuffered FT2232D breakout board +with a special EEPROM configuration as the JTAG adapter, as described in the +Unbuffered-FT2232x-JTAG article. ADBUS0 through ADBUS3 are wired to standard +JTAG signals as required by FTDI and ADBUS7 (acting as a GPIO) is wired to the +XDS_RESET line on JTAG connector pin 2. This choice of using a generic FT2232D +breakout board as opposed to a more purpose-made "professional" JTAG adapter +was made deliberately in order to force the user to make a mental shift +regarding reset signals: any standard JTAG adapter product will have two reset +outputs designated as TRST and SRST, but the XDS_RESET signal on the FCDEV3B +does not correspond to either of those. But a generic (non-JTAG-specific) +FT2232x breakout board does not have TRST or SRST, it only has ADBUS and ACBUS +pins that become GPIOs in MPSSE mode, allowing the user to break out of the +TRST and SRST mentality: you just have a bunch of GPIOs, then arbitrarily pick +one of those GPIOs and connect it to XDS_RESET, *without* associating it with +either TRST or SRST. + +The full set of needed wire connections is thus: + +FT2232D signal FCDEV3B JTAG signal +----------------------------------- +ADBUS0 TCK (pin 11) +ADBUS1 TDI (pin 3) +ADBUS2 TDO (pin 7) +ADBUS3 TMS (pin 1) +ADBUS7 XDS_RESET (pin 2) + +You will also need to connect at least one ground pin, hence 6 wires in total. +There is no need to connect the undocumented and non-understood EMU0 and EMU1 +signals - we don't know what to do with them and we work without them. This +wiring arrangement and all functionality described in this article work exactly +the same way on both D-Sample and FCDEV3B boards. You will also need to +reprogram the EEPROM on the FT2232D board as described in the +Unbuffered-FT2232x-JTAG article *before* you connect it to the Calypso target +board. + +One can also connect just the 4 JTAG wires, without reset: there are some +historical commercial phones and modems on which JTAG lines are accessible, but +Iota nTESTRESET is not, or perhaps nTESTRESET is accessible, but you don't feel +like replicating the transistor circuit that is required in order to drive it +safely - the circuit that is present on development boards, but not on hacked-up +phones and modems. In that case you will still be able to halt an already- +running Calypso, but of course you won't be able to exercise reset_halt or +reset_run operations described below. + +Unpowered FT2232D adapter quirk +=============================== + +If you connect the FT2232D board to the FCDEV3B as described above, including +the XDS_RESET signal and ground, you will notice the following quirk: if the +custom-crimped JTAG cable is connected between the two boards, but the FT2232D +board is not plugged into a USB host (has no USB power), the FCDEV3B will be +held down in test reset: the green LED will be off, and neither button on the +board will do anything. The FCDEV3B will be released from this reset and will +boot in test reset mode with the green LED on the moment you plug the FT2232D +board into your USB host. + +Running OpenOCD +=============== + +With the FT2232D board plugged into your host PC or laptop and programmed with +the custom USB ID of 0403:7151, you can run OpenOCD with the custom config file +presented in the calypso-jtag directory in this repository: + +openocd -f ft2232d-unbuf-poc.cfg + +Being a proof of concept, this OpenOCD config file does not follow any of the +guidelines regarding separation between adapters and targets, but is fully +monolithic instead. This config is written to work with openocd-0.10.0 +(depends on the new ftdi driver), but does NOT use the target/ti_calypso.cfg +fragment that has been included in mainline OpenOCD for quite some time: in the +Mother's opinion, the latter is bogus. If someone wishes to bring Calypso +support in the mainline OpenOCD distribution up to par, I do not have any +advice or guidance for you: it is your job, not mine. The present PoC config +that is rather antagonistic to mainline OpenOCD, its framework and its +guidelines will always remain our standard answer to FreeCalypso customers +asking how to make JTAG work. + +When you run OpenOCD as above, the FCDEV3B target needs to be in the running +state with the green LED on. OpenOCD will exercise and verify the scan chain, +but it won't issue any resets or halts on its own, thus whatever code was +running on the board won't be disturbed in any way by the act of running +OpenOCD. You can then reset and/or halt the target as desired with our custom +commands (Tcl procedures) as described below. + +Halting the Calypso without a reset +=================================== + +To halt an already-running Calypso ARM7 core without a reset, stopping it at +whatever point it happens to be in its code execution, execute this sequence: + +enable_halt; halt + +The enable_halt step is a custom Tcl procedure added by us, issuing the +mysterious 0xB instruction and DR scan that are needed in order to enable halts +on TI's modified version of the ARM7TDMI core. Once you have halted as above, +you can resume and halt again without needing to re-execute the enable_halt +step; the only time when the enable_halt steps will need to be repeated is when +the Calypso is reset. + +You can safely halt the Calypso in this manner when the flash is blank and the +boot ROM waits forever for a serial download, when you have loaded a RAM image +with fc-xram -j and the target is left in loadagent, or when one of our standard +firmwares is running; in all of these states the Calypso watchdog timer is +disabled. However, if you are going to halt the Calypso when the watchdog timer +is running, you will need to execute our wd (watchdog disable) command quickly +after the halt, before the watchdog timer is allowed to expire. A simple way +would be: + +enable_halt; halt; wd + +The wd command (Tcl procedure) name was deliberately made short so it can be +typed quickly with fingers if need be. + +Resetting with or without a halt +================================ + +We don't support OpenOCD's standard reset command because we found it too +difficult to override its built-in assumptions which are wrong for our Calypso. +Instead we have our own reset_halt and reset_run custom commands (Tcl +procedures) that replace OpenOCD's standard 'reset halt' and 'reset run', +respectively. + +The reset_run command will reset the board without halting the Calypso, letting +it boot and run normally. It is equivalent to pressing the RESET button on the +board with your finger, except that it also re-initializes OpenOCD's scan scain +and "target examination" state which would otherwise get confused. + +The reset_halt command will reset the board and halt the Calypso immediately as +it comes out of reset, halting at the reset vector before the first instruction +of the boot ROM code (or the first instruction from external memory if operating +on a D-Sample board with the boot switch set to external) is executed. The +necessary disabling of the watchdog timer (wd procedure call) is already built +into the reset_halt Tcl procedure; except for this wd step, all Calypso and Iota +registers will be in their most pristine reset state. + +Recovering bricked Compal phones +================================ + +Some Mot C1xx phones have Calypso JTAG signals brought out to accessible contact +pads, allowing a way to recover from a bricked flash bootloader via JTAG. +However, they do not bring out Iota nTESTRESET, instead they bring out a signal +which they call DLPWR, which is really Iota RPWON. A procedure similar to our +reset_halt would need to be performed as the first step in the recovery +sequence, but it would need to be modified to work with DLPWR instead of +XDS_RESET. The RPWON aka DLPWR signal will need to be driven with an OC/OD +driver (it is internally pulled up to raw VBAT, which is not a safe voltage for +standard 3.3V logic), and the switch-on and boot sequence will be triggered +when this signal is pulled low, i.e., transitions from high to low. The +subsequent release transition (from low back to pull-up high) does not matter, +i.e., RPWON may be permanently pulled down as the Calypso boots and runs, very +much unlike nTESTRESET or XDS_RESET. + +It will be up to you to design whatever circuit you wish to use to produce an +OC/OD driver that can be triggered from OpenOCD, but connecting RPWON aka DLPWR +directly to an FT2232x I/O pin is not acceptable. Copying the circuit from +TI/FC development boards that propagates XDS_RESET into nTESTRESET won't work: +this circuit only works when the V-IO regulator is already on, but RPWON is not +a reset and will need to be triggered when the chipset is fully "cold". + +You will also need to figure out the appropriate timing. You will need to +insert a certain delay between RPWON assertion and the 'jtag arp_init' step in +our reset_halt procedure: the VRPC state machine in the Iota chip will do a +bunch of work between sensing a low on RPWON and releasing the Calypso from +reset via ON_nOFF, and until then the JTAG scan chain won't work. But the +delay cannot be too long either, or you won't halt the Calypso before it starts +executing bogus code from the phone's bricked flash. + +Once you do get a working reset_halt variant, the following steps will be +straightforward: + +1) Run fc-loadtool -h compal -c none /dev/ttyXXX on the serial port connected + to the phone's headset jack; + +2) Enable the boot ROM and jump to it with these commands: + + mwh 0xFFFFFB10 0x100 + resume 0 + +The boot ROM will run while fc-loadtool is sending its beacons, fc-loadtool +will load and run loadagent, and you can then recover the flash.