FreeCalypso > hg > freecalypso-hwlab
view doc/Calypso-OpenOCD-Howto @ 71:bac08ce19c08
DUART28C USB ID assigned
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 30 Jul 2020 04:53:27 +0000 |
parents | 6d02f30e35ad |
children |
line wrap: on
line source
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 step 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 either: 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. Lack of performance optimizations ================================= Our PoC OpenOCD-on-Calypso config does not set up a work area (an area of system RAM that is declared as a scratchpad for OpenOCD), nor does it enable arm7_9 dcc_downloads or arm7_9 fast_memory_access. These omissions are intentional, as those performance optimizations are outside of the scope of what I set out to do, which is to prove Calypso JTAG as working and provide a "golden reference" setup. If you wish to set up an area in Calypso IRAM as a work area for OpenOCD, which is a prerequisite for arm7_9 dcc_downloads, you will need to choose the location based on your specific application - whether a given area will be suitable or not will depend on exactly what you are debugging and exactly what you are trying to do, which is once again outside of the scope of this PoC.