changeset 18:7ba5c951803c

Calypso-JTAG-notes article written
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 24 Jun 2019 20:01:53 +0000
parents 3d65bdaf00da
children f68ca40fa5c1
files Calypso-JTAG-notes
diffstat 1 files changed, 349 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Calypso-JTAG-notes	Mon Jun 24 20:01:53 2019 +0000
@@ -0,0 +1,349 @@
+This document describes the quirks of Calypso JTAG in an abstract, tool-
+independent sense, and also covers the little bit of experience we've had with
+TI's original official tools, but does not delve into OpenOCD specifics.
+For OpenOCD-on-Calypso custom config and instructions, please refer to the
+freecalyps-hwlab repository - but the present document should still be read
+first.
+
+Unconventional reset structure
+==============================
+
+The first major way in which the JTAG interface on Calypso development boards
+(or more generally, what is available in the Calypso+Iota chipset) differs from
+"canonical" JTAG is that this chipset does NOT have reset signals that are
+anything like classic TRST or SRST.  Instead there is only one bundled-with-JTAG
+reset signal (we call it XDS_RESET) which is turned into Iota nTESTRESET through
+a transistor circuit - please refer to the Calypso-test-reset article.  Aside
+from its effects on the VRPC state machine described in that article, this test
+reset can be thought of as a simultaneous combination of an equivalent of TRST
+(all JTAG logic is hard-reset), an equivalent of SRST (the Calypso is fully
+reset and proceeds with a cold boot) and more (all hardware is reset at a very
+deep level), but comparisons to classic TRST and SRST aren't really appropriate
+as the latter signals simply don't exist in our chipset.
+
+However, despite its highly unconventional nature, this XDS_RESET signal
+provided along with JTAG on TI's development boards performs a very important
+function: this combination of JTAG and test reset allows a "reset and hold
+still" maneuvre where all hardware is put into its pristine state with a very
+deep reset, but the ARM7 CPU is halted before it gets a chance to execute any
+instructions from the reset vector.  This ability is not particularly important
+on current Calypso hardware with a working and enabled boot ROM, but it was
+vital on earlier platforms without this boot ROM: if the flash is blank or
+contains a bad code image, or if RAM is mapped onto the boot chip select
+instead of flash, allowing the ARM7 core to execute garbage out of reset is
+bad, whereas having a "reset and hold still" ability allows guaranteed reliable
+recovery and bootstrapping from a blank or bricked state.  As explained later
+in this article, this "reset and hold still" maneuvre is executed by first
+giving the target a test reset pulse (which unstoppably blows away all prior hw
+state), then immediately (the timing is critical) performing certain
+manipulations via the JTAG scan chain - thus the bundling of the XDS_RESET
+signal with JTAG is important.
+
+EMU0 and EMU1 signals
+=====================
+
+In addition to the 4 standard JTAG signals TCK, TDI, TDO and TMS, the Calypso
+provides two TI-proprietary signals called EMU0 and EMU1.  (The test reset goes
+to the Iota ABB, not to the Calypso.)  These EMU0 and EMU1 signals are brought
+out to the 14-pin JTAG connector on TI's D-Sample and E-Sample boards, and also
+on our FCDEV3B.
+
+The function of these two signals is completely unknown: all we know is that
+they are listed as "bidirectional in/out" in the cal000.pdf document, and that
+same-named signals also exist on TI's general-purpose DSP chips, both C54x and
+the newer families, where they are also very poorly documented.  We don't know
+what these EMU0/1 signals do on the Calypso, and it is a particular unknown
+whether they are specific to the DSP part or if the ARM7 part can also make use
+of them somehow.
+
+I (Mother Mychaela) previously thought that these signals might facilitate a
+way to halt the ARM7 core without going through the scan chain, or a different
+way to halt directly out of reset than the one we ultimately found, but a
+recent experiment has shown that pulling either or both of these signals low
+(they are pulled up on target boards) has absolutely no visible effect on ARM7
+code execution, whether they are pulled low coming out of test reset or while
+running.  Thus until we recover more understanding of what is going on inside
+the chip, we are going to ignore these two signals and leave them unconnected.
+
+Iota not included in the JTAG scan chain
+========================================
+
+In addition to the Calypso chip itself (the DBB), the Iota ABB chip also has
+JTAG pins and could potentially be included in the scan chain.  However, this
+wiring arrangement is not typically used: both on TI's D-Sample board and on
+our own FCDEV3B (based on Leonardo schematics) the JTAG interface is wired only
+to the Calypso and not to Iota.  The same arrangement has also been found in
+all historical commercial phones and modems that provide a JTAG interface.
+
+We don't have any plans to change this arrangement in any of our future designs:
+in the absence of 100% complete understanding of the internals of both chips,
+there is no telling what unexpected gotcha may occur if the Iota chip is
+included in the same scan chain as the Calypso, hence we are not doing that.
+
+ARM7 and C54x DSP cores
+=======================
+
+The regular JTAG scan chain inside the Calypso goes through two TAPs
+corresponding to the two processor cores.  The ARM7 TAP with a 4-bit IR is
+closer to TDI, and the C54x DSP TAP with an 8-bit IR is closer to TDO.  The
+debug interface to the ARM7 core through its respective TAP is consistent with
+public ARM7TDMI documentation from ARM except for one important quirk described
+below, but we know absolutely nothing about the DSP TAP and its debug protocol
+other than how to put it into BYPASS so we can operate on the ARM.
+
+It appears from passing references in some TI documents that they did intend to
+have an ability to debug the Calypso DSP via JTAG "emulation", and TI's CCS
+software working through TI's XDS510 or XDS560 hardware (the same setup that
+successfully connects to the ARM7 part of the Calypso) supports C54x targets.
+However, we have no idea how any potential JTAG access to the DSP would interact
+with its reset control coming from the ARM or with its power saving modes, and
+it is very likely that there are some security mechanisms restricting debug
+access to the DSP (perhaps needing some secret key to unlock it), thus being
+able to debug the DSP via JTAG is not something we can realistically hope for
+unless we either buy out the complete chip design from TI or physically
+reverse-engineer the chip transistor by transistor, both options being equally
+cost-prohibitive.  At our current level of budgetary means, our ability to use
+the JTAG interface on the Calypso is limited to the ARM7 part, not the DSP.
+
+Non-standard extension to the ARM7TDMI TAP
+==========================================
+
+We know that TI made at least one non-standard extension to the ARM7TDMI TAP in
+the Calypso because it implements at least one additional opcode that does not
+appear in any public documentation from ARM.  When connecting to this ARM7
+target, TI's CCS software working through XDS510 or XDS560 hardware apparently
+scans a 0xB opcode (4'b1011) through the IR, and then apparently scans 2'b10
+through the 2-bit DR selected by this opcode.  (I said "apparently" because so
+far the only people who have actually sniffed the JTAG communications produced
+by the XDS+CCS combo were OsmocomBB people, not anyone from the FreeCalypso
+team, hence we don't have any authentic knowledge currently.)  Experiments with
+OpenOCD show that the just-described sequence of IR and DR scans with an
+unknown instruction and an unknown data register is necessary in order to allow
+halting the ARM7 core: if we try to halt it in the standard ARM7TDMI way (either
+via DBGRQ or via a catch-all breakpoint unit setup) without doing the magic
+sequence first, no halt is effected.
+
+Fortunately though, after we issue the non-understood magic sequence once, all
+subsequent ARM7TDMI halt/resume manipulations done in the standard way appear
+to work just fine, no more quirks.  The only time when the "halt unlock" magic
+sequence needs to be repeated is after a reset, which is expected.
+
+Interaction with the watchdog timer
+===================================
+
+The Calypso chip includes a watchdog timer feature; if this watchdog timer is
+enabled and allowed to expire, it effects a fairly deep reset of the chip.  The
+Calypso boot ROM code and most firmware designs do a step early on to disable
+this watchdog, and it is not subsequently re-enabled except to effect a reboot
+when so desired, but as the ARM7 core first comes out of reset and starts
+executing instructions from the reset vector (whether ROM or external memory),
+the watchdog timer is enabled and ticking.  This watchdog timer interacts with
+JTAG as follows:
+
+1) When the ARM7 core is halted via JTAG, the watchdog timer (if enabled) is
+   NOT stopped or paused, but keeps ticking.
+
+2) If a watchdog reset occurs while the ARM7 core is halted, everything goes
+   out of whack, consistent with the note in standard ARM7TDMI documentation
+   which says that a reset must not be applied to the core while it is in debug
+   halt state.
+
+Therefore, if the ARM7 core is to be halted at a time when the watchdog timer
+is enabled and ticking, the halt operation must be quickly followed by two
+system bus write operations (mwh command in OpenOCD) to the WATCHDOG_TIM_MODE
+register, executing the watchdog disable sequence before the timer is allowed
+to expire while halted.
+
+JTAG clock speed
+================
+
+It is often stated that the JTAG clock speed must be no greater than 1/6 of the
+system clock speed when talking to ARM cores, and that JTAG access is blocked
+when the core goes into a power saving mode with the clock stopped.  Neither of
+these constraints applies to our beloved Calypso though: the stated issues occur
+in chip designs which internally synchronize JTAG signals including TCK to their
+system clock, but Calypso and its predecessors don't do that, they use the hard
+macrocell version of the ARM7TDMI core instead, use TCK directly to clock JTAG-
+specific logic and perform "hard" clock switching for debug mode.
+
+According to the available cal000_a.pdf document, the maximum TCK frequency
+supported by the Calypso is 10 MHz, which also appears to be the only TCK
+frequency which TI's older XDS510 "emulator" pods can produce without hardware
+modifications.  This 10 MHz TCK frequency can be used no matter what frequency
+is fed to Calypso's main CLKTCXO clock input or what frequency the ARM7 core is
+configured to run at, and JTAG keeps working even when the main clock is
+completely stopped.
+
+It is possible to halt the Calypso ARM7 core when it is in a sleep mode, even
+in deep sleep: manipulation of internal scan chain 2 to set DBGRQ is a JTAG-only
+operation, contained entirely in the TCK clock domain, thus it works even with
+the main VCXO stopped, and the actual halt occurs on wakeup when the ARM7 core
+regains its regular clock and sees the internal DBGRQ signal asserted.
+
+Halting immediately out of reset
+================================
+
+To me (Mother Mychaela) it always seemed evident that the Calypso and its
+predecessors had to have some way to perform a "reset and hold still" maneuvre,
+as this capability was absolutely essential for deterministic bootstrapping and
+recovery of boards before the Calypso boot ROM subsumed that function.  However,
+the exact manipulations required to achieve this effect have remained elusive
+for a long time until I found the answer in May-June of 2019.  The trick is NOT
+done through EMU0/1 pins like I once thought, and the method used on many other
+chips involving classic TRST and SRST signals is clearly not applicable to the
+Calypso given its very different reset structure.
+
+The answer lies in the clocking architecture of TI GSM chipsets, involving a
+VCXO that is started and stopped and a 32.768 kHz clock which is always running.
+When the Calypso starts its boot process in response to the ON_nOFF signal
+going from low to high (in the XDS-triggered test reset scenario this event
+immediately follows the release of external reset), the main VCXO is off (i.e.,
+it hasn't been started yet) and only the 32.768 kHz clock is running.  At this
+point the ARM7 core receives no clock at all (the 32.768 kHz clock is never fed
+to the ARM7), and the ULPD block (the same block that handles deep sleep) goes
+through the sequence of first enabling the main VCXO, then waiting for it to
+stabilize.  This sequence takes about 8192 cycles of the slow clock (about
+250 ms), and only at the completion of this sequence the ARM7 core gets its
+first clock.  But during that 250 ms time window the JTAG logic is out of its
+reset and functioning, and it can be operated because Calypso JTAG does not
+depend on the main ARM clock which is stopped.
+
+The following sequence of steps successfully achieves the effect of resetting
+the Calypso+Iota chipset and all board-level peripherals that are subservient
+to it, and halting the Calypso directly at the reset vector before the first
+instruction is executed:
+
+1) Give the chipset a test reset pulse via the XDS_RESET line; the exact
+   required duration is not known, but my OpenOCD-based proof of concept gives
+   a 50 ms pulse.
+
+2) Immediately after releasing the reset or after a short delay (my PoC does a
+   10 ms delay), start exercising the JTAG scan chain, which has been fully
+   reset - it will be responsive at this point.
+
+3) Perform the "magic" IR and DR scans to enable halting ability, just like we
+   do when we wish to halt an already-running Calypso.
+
+4) Going through scan chain 2 inside the ARM7TDMI TAP, set the DBGRQ bit.
+   All steps up to this one must happen before Calypso ULPD enables the
+   VCXO-derived clock to the ARM7.
+
+5) Also going through scan chain 2, poll and wait for DBGACK to get set,
+   indicating that the ARM7TDMI core halted - this event will happen when the
+   core gets its first clocks.
+
+6) Once the ARM7TDMI core is halted, perform the two mwh operations to the
+   0xFFFFF804 register (WATCHDOG_TIM_MODE) to disable the watchdog, otherwise
+   it will generate another internal reset and mess up the system state.
+
+We never found any built-in provision in TI's CCS (see below) or any script for
+CCS that does the above, instead I (Mother Mychaela) found it on my own by
+thinking about how it could possibly be done, and proved the idea working
+with an OpenOCD setup presented in the freecalypso-hwlab repository.
+
+Original official TI tools
+==========================
+
+TI's original and official tool for operating on Calypso JTAG was their Code
+Composer Studio (CCS) software, working through TI's XDS510 and XDS560
+"emulator" hardware.  The original hardware solution was the XDS510, and I mean
+the original XDS510 which was an ISA card made by TI themselves, not any of the
+later "XDS510-class" "emulators" made by companies acting as TI's 3rd-party
+partners.  The next successor to this original XDS510 was the original XDS560,
+also made by TI themselves and distinct from the later "XDS560-class" devices
+by TI's 3rd-party partner companies.  The original XDS560 is a PCI card rather
+than ISA, thus a little easier to get working in 2019, and also more readily
+available on ebay.  Both XDS510 and XDS560 consist of a desktop PC card (ISA or
+PCI) and an active pod, and the pod has a non-detachable target connection cable
+coming out of it, terminating in a female connector mating with the TI-style
+14-pin JTAG header.  The pod connector fits perfectly to TI's original D-Sample
+board, but on our FCDEV3B it fails to fit because the JTAG and dual UART headers
+are too close together.  Therefore, anyone who is interested in connecting TI's
+original XDS510 or XDS560 to an FCDEV3B would need to get some male-to-female
+jumper wires or make a custom-crimped interposer cable.
+
+The version of CCS which we found to work with these "emulator" adapters (both
+XDS510 and XDS560) and with Calypso targets is this one:
+
+ftp://ftp.freecalypso.org/pub/GSM/TI_tools/CCS/CCS_3.3.83.20_win32.zip
+
+In order to get this CCS to work with a Calypso target, you will need to create
+a "custom board" configuration in CCS setup - none of the predefined board
+configs shipped with CCS will work.  To create the needed "custom board" config,
+select your "emulator" (XDS510 or XDS560), then add an ARM7 target and a
+TMS320C5400 target in this order, which is the order from TDI to TDO.  With this
+custom config saved, running CCS brings up what they call the Parallel Debug
+Manager, which supposedly supports coordinated debugging of both ARM and DSP
+cores.  However, I (Mother Mychaela) have not tried connecting to the DSP part,
+only ARM7; another FreeCalypso community member who also got a working XDS510
+setup talking to an FCDEV3B did try it, but saw what appears to be garbage.  As
+discussed earlier in this article, we are completely in the blind here, hence
+this direction is not being seriously explored at the present.
+
+In order to play with just the ARM7 core, leaving the DSP alone, select the
+ARM7 target in the Open menu in Parallel Debug Manager - the main CCS debug
+window will then open, and it will be specific to the ARM7 target.  In my own
+testing all further operations were done from the latter window and its menus.
+
+Reset with TI's tools
+---------------------
+
+Both XDS510 and XDS560 "emulators" have only one reset output; on TI's general-
+purpose DSP development boards outside of the GSM Skunkworks division this one
+reset line was TRST, whereas on D-Sample and Leonardo boards (and on our
+FCDEV3B) this signal is repurposed to drive Iota nTESTRESET through a clever
+transistor circuit.  TI's general-purpose (non-GSM) DSP chips and boards have
+internal pull-downs on TRST rather than pull-ups (JTAG logic permanently held
+down in reset when no "emulator" is connected), hence both XDS510 and XDS560
+pods drive this signal with an active push-pull driver - which is why Calypso
+development boards include the special transistor circuit rather than connect
+the XDS_RESET line (as we call it) directly to internal nTESTRESET.
+
+Prior to initialization, a "cold" XDS560 pod has its reset output held low,
+thus the target board will be held down in test reset and will appear completely
+unresponsive.  To initialize the XDS560 and release it from reset, select
+"Emulator Reset" from the Debug menu.  For this operation to succeed, the LDO
+regulators in the Iota ABB need to be turned on, putting out 2.8 V on the V-IO
+rail which is used as the target voltage reference by the XDS560 pod, so you
+will probably need to press either the PWON button or the RESET button on the
+FCDEV3B initially - and if the green LED stays off after that button press, you
+know that the board is being held down in test reset by the XDS560 pod.  Then
+do the "Emulator Reset" operation, at which point the green LED will turn on
+and the board will boot normally.  From this point onward, doing a repeated
+"Emulator Reset" operation causes a low-then-high pulse to be put out on the
+XDS_RESET line, resetting the board and once again causing it to go through a
+fresh boot.
+
+Connecting to the ARM7 core and halting it
+------------------------------------------
+
+Once the XDS560 has been initialized and the target board has been lifted out
+of test reset with the "Emulator Reset" operation, you can execute the
+"Connect target" operation, also in the Debug menu.  This operation produces a
+successful halt (I can only guess that this step is the point at which the
+mysterious 0xB JTAG instruction and the unknown 2-bit register scan are issued,
+unlocking the halting ability on this modified ARM7TDMI core), but the halt
+happens at whichever point the ARM7 core happens to be in its code execution,
+i.e., the generic, non-GSM-specific CCS has no knowledge of the peculiar timing
+sequence that is required to achieve a halt directly out of reset on the
+Calypso.  It is my (Mychaela's) guess that CCS probably has some scripting
+ability for more advanced users, and that TI's GSM Skunkworks division used
+this custom scripting mechanism to do a sequence of {Emulator reset, then
+connect to target and halt, then execute two register writes to disable the
+watchdog} with machine rather human timing between the steps.  Machine rather
+than human timing is required in order to hit the 250 ms window between the
+release of reset and the beginning of ARM core execution, and also to disable
+the watchdog after the halt via two register writes before it goes off.
+
+Using OpenOCD on Calypso targets
+================================
+
+Building on top of the work that was done almost a decade earlier by some people
+in the OsmocomBB camp (they sniffed the magic "halt unlock" sequence from an
+XDS+CCS setup and gained the ability to halt an already-running Calypso with
+OpenOCD, albeit without the reset magic) and adding the more in-depth
+understanding provided by Mother Mychaela, we now have the ability to use
+OpenOCD with a simple FT2232D adapter (instead of TI's XDS+CCS) to connect to
+JTAG on TI/FC development boards, both D-Sample and FCDEV3B, gaining the power
+of Free Software instead of proprietary tools.  For the details, please refer
+to the freecalypso-hwlab repository.