Debug Interfaces: UART, JTAG & Trace
Three hardware interfaces give you visibility below the OS: UART (serial console — passive, always-on log stream at 115200n8), JTAG/SWD (CPU debug — halt, step, inspect registers and memory), and CoreSight Trace (non-invasive execution recording via ETM/ETF/ETR). Each has different intrusiveness, bandwidth, and mode availability. UART is your daily tool. JTAG is for hard crashes. CoreSight is for performance analysis. Debug policy fuses on production boards can disable JTAG and restrict trace — always know your board’s fuse state before planning a debug session.
Every software debug technique in this curriculum — QFIL over EDL, <GlossaryTooltip client:load id="adb">adb logcat</GlossaryTooltip>, QNX slog2info, crashdump collection, TRACE32 post-mortem — ultimately rides on one of three physical interfaces. On SA8155P/SA8295P cockpit platforms running QNX + AAOS under QHEE, you cannot assume all three are available on every board. This page explains what each interface does, how to wire it, when to reach for it, and what fuse policy can take away. When software debug tools lie to you (and they will), hardware interfaces tell the truth.
UART / Serial Console
Section titled “UART / Serial Console”The serial console is the most important debug interface on an automotive bench. Always connect UART first. It requires no special probe, works from the
Electrical and Physical Setup
Section titled “Electrical and Physical Setup”Qualcomm automotive standard: 115200n8 (115200 baud, 8 data bits, no parity, 1 stop bit, no flow control) at 3.3V TTL — not RS-232 ±12V. Connect a USB-to-UART adapter (FTDI FT232RL preferred; CP2102/CH340 work) to the board debug UART header. Pin order on ADP boards: TX, RX, GND (check schematic — carriers may label from DUT perspective).
Wiring rule: Connect GND first, then TX/RX. UART TX on the adapter connects to RX on the board, and vice versa (crossover). If you see nothing, swap TX/RX once before chasing software.
Hypervisor Mux Behavior
Section titled “Hypervisor Mux Behavior”On QHEE hypervisor ADP boards, QNX and AAOS share the same physical UART. Output is interleaved on one stream. Learn to read the prefixes:
| Source | Prefix / Format | Example |
|---|---|---|
| PBL / XBL / ABL | Stage-specific banners, no Linux timestamp | B - 12345678 PBL... |
| QNX | Plain text, no timestamp prefix | Starting QNX Neutrino... |
| AAOS (Linux) | [seconds.microseconds] kernel timestamp |
[ 3.452891] init: ... |
| Firehose (EDL) | XML command/response over UART (secondary to USB) | <?xml version="1.0"?> |
When debugging a multi-VM boot hang, scroll the UART capture and mark which stage last printed. That tells you whether the failure is in XBL, QHEE guest load, QNX IFS, or AAOS kernel init — without guessing from USB enumeration alone.
Host Terminal Setup
Section titled “Host Terminal Setup”# Linux — picocom (Ctrl-A Ctrl-X to exit), minicom, or screenpicocom -b 115200 /dev/ttyUSB0minicom -D /dev/ttyUSB0 -b 115200screen /dev/ttyUSB0 115200
# macOS — device usually at /dev/cu.usbserial-*picocom -b 115200 /dev/cu.usbserial-XXXXscreen /dev/cu.usbserial-XXXX 115200
# Always tee to a timestamped log (Linux)picocom -b 115200 /dev/ttyUSB0 | tee -a uart_$(date +%Y%m%d_%H%M%S).log
# macOS without picocomscript -q uart_$(date +%Y%m%d_%H%M%S).log screen /dev/cu.usbserial-XXXX 115200Device Tree Configuration
Section titled “Device Tree Configuration”The BSP device tree controls whether UART is enabled and which port is the boot console. Page 5.6 covers the full DTS hierarchy; the debug-relevant nodes are:
/ { chosen { stdout-path = "serial0:115200n8"; };};
&serial0 { status = "okay"; compatible = "qcom,geni-debug-uart";};| Symptom | DTS Check |
|---|---|
| UART silent after flashing production BSP | status = "disabled" on debug UART node |
| Garbage at 115200 | Wrong stdout-path baud suffix or wrong QUP instance |
| Works on ADP, not carrier | OEM overlay disabled debug UART for production |
UART works in all boot modes, including EDL. Firehose primarily uses USB (QDLoader 9008), but XML programmer commands can also traverse UART on some platforms — useful when USB routing is broken but serial is alive.
You need to debug a boot failure that happens before UART output starts. What interface can help?
Reveal Answer
JTAG (or SWD if exposed) through the DAP is your only option below UART — power off, attach TRACE32 or OpenOCD, then halt at reset and inspect PC/register state before any printk runs. Also scope VDD_CX and the 19.2 MHz reference crystal — silent UART often means PMIC sequencing or clock failure, not a missing BSP. Confirm fuse-open status first; JTAG_DISABLE blocks this path permanently on production units.
JTAG and SWD
Section titled “JTAG and SWD”When UART shows nothing useful — boot hangs before any print, CPU exception before OS init, or SDI with cores halted — you need CPU-level debug. JTAG and SWD connect to the
JTAG: The 4-Wire (+ Clock) Interface
Section titled “JTAG: The 4-Wire (+ Clock) Interface”JTAG (Joint Test Action Group) uses five signals:
| Signal | Direction | Purpose |
|---|---|---|
| TDI | Host → Target | Test Data In — serial data into the scan chain |
| TDO | Target → Host | Test Data Out — serial data out of the scan chain |
| TMS | Host → Target | Test Mode Select — state machine control |
| TCK | Host → Target | Test Clock — synchronizes all JTAG operations |
| TRST | Host → Target | Test Reset (optional) — async reset of debug logic |
Through the DAP, a debugger can:
- Halt and resume CPU cores
- Single-step instructions
- Read and write general-purpose registers
- Read and write memory (including device registers)
- Set hardware breakpoints and watchpoints
- Inspect cache and TLB state (debugger-dependent)
SWD: Two-Wire Alternative
Section titled “SWD: Two-Wire Alternative”SWD (Serial Wire Debug) replaces the four data/clock JTAG wires with two:
| Signal | Purpose |
|---|---|
| SWDIO | Bidirectional data |
| SWCLK | Clock |
SWD provides the same DAP capabilities as JTAG with fewer pins. Not all Qualcomm automotive boards expose SWD — check your ADP schematic. Many automotive reference boards use the standard 20-pin ARM JTAG header instead.
Multi-Core JTAG Chain
Section titled “Multi-Core JTAG Chain”On SA8155P/SA8295P, the JTAG scan chain includes multiple cores and subsystems. The debugger must select the correct TAP (Test Access Port) in the chain before halt/step operations take effect on the intended core.
flowchart LR
PROBE["Debug Probe\n(TRACE32 / OpenOCD)"]
DAP["DAP\n(Debug Access Port)"]
C0["Kryo Core 0"]
C1["Kryo Core 1"]
C2["Kryo Core 2"]
C3["Kryo Core 3"]
C4["Kryo Core 4"]
C5["Kryo Core 5"]
C6["Kryo Core 6"]
C7["Kryo Core 7"]
DSP["Hexagon DSP\n(if accessible)"]
CS["CoreSight\n(ETM, ETF, funnel)"]
PROBE --> DAP
DAP --> C0 --> C1 --> C2 --> C3 --> C4 --> C5 --> C6 --> C7 --> DSP --> CS
Practical implication: Attaching TRACE32 and halting “the CPU” may halt core 0 while your QNX driver runs on core 3. Always verify which core owns the code under investigation. Qualcomm T32 scripts for SA8155P/SA8295P pre-configure core selection for common automotive bring-up tasks.
| Tool | Type | Automotive Use |
|---|---|---|
| Lauterbach TRACE32 | Commercial (industry standard) | Full JTAG + trace, Qualcomm scripts, SDI post-crash |
| ARM DSTREAM | Commercial | JTAG/SWD + CoreSight trace |
| OpenOCD | Open source | Basic halt/step/memory — limited Qualcomm script support |
| Qualcomm T32 scripts | Vendor automation | Pre-built SA8155P/SA8295P core maps, TZ-aware attach sequences |
Use JTAG when UART fails you: boot hang before first character (ROM/XBL stuck), CPU exception before OS init (need faulting PC), SDI with halted cores, or register-level MMIO debug the driver never logs.
CRITICAL RULE: No Hot-Plug
Section titled “CRITICAL RULE: No Hot-Plug”Never connect or disconnect JTAG with the board powered on. Hot-plugging can damage the DAP and permanently disable debug access on that SoC. Power off the board, attach the probe, power on, then connect from the host debugger. Reverse the sequence on teardown.
CoreSight Trace Architecture
Section titled “CoreSight Trace Architecture”JTAG stops the CPU to inspect state. CoreSight trace records execution without halting — a flight recorder at full speed. This is how you answer “where did those 16 milliseconds go?” or “what was the exact instruction sequence before the race?”
CoreSight Components
Section titled “CoreSight Components”| Component | Abbreviation | Role |
|---|---|---|
| Embedded Trace Macrocell | ETM | One per CPU core — records instruction flow (branch addresses, exceptions) |
| Embedded Trace FIFO | ETF | On-chip SRAM buffer — holds trace data when external bandwidth is limited |
| Embedded Trace Router | ETR | Routes trace data to system memory (DDR) or external trace port |
| Trace Funnel | — | Merges multiple ETM streams into one downstream path |
| TPIU | — | Trace Port Interface Unit — drives off-chip trace pins to external probe |
flowchart TB
subgraph cores ["CPU Cores"]
C0["Kryo Core 0"]
C1["Kryo Core 1"]
C2["Kryo Core 2"]
C3["Kryo Core 3"]
end
subgraph etm ["ETM (one per core)"]
ETM0["ETM0"]
ETM1["ETM1"]
ETM2["ETM2"]
ETM3["ETM3"]
end
FUNNEL["Trace Funnel"]
ETF["ETF\n(on-chip buffer)"]
ETR["ETR\n(router)"]
DDR["DDR Trace Buffer\n(system memory)"]
TPIU["TPIU\n(external port)"]
PROBE["Trace Probe\n(PowerTrace / DSTREAM)"]
C0 --> ETM0
C1 --> ETM1
C2 --> ETM2
C3 --> ETM3
ETM0 --> FUNNEL
ETM1 --> FUNNEL
ETM2 --> FUNNEL
ETM3 --> FUNNEL
FUNNEL --> ETF
FUNNEL --> ETR
ETR --> DDR
ETR --> TPIU
TPIU --> PROBE
ETF --> PROBE
Repeat the ETM-per-core pattern for all eight Kryo cores on SA8155P/SA8295P. Hexagon DSP trace is a separate path — availability depends on fuse policy and BSP configuration.
Use Cases
Section titled “Use Cases”| Problem | Trace Approach |
|---|---|
| Performance profiling | Record ETM for 10 seconds during lag — decode to see hot functions |
| Race condition | Capture instruction sequence on both cores around the shared variable access |
| Interrupt latency | Measure cycles from IRQ assert to handler entry via timestamped trace |
| Scheduler jitter | Compare QNX thread switches against AAOS vCPU scheduling on adjacent cores |
Requirements
Section titled “Requirements”| Requirement | Notes |
|---|---|
| Trace-capable probe | Lauterbach PowerTrace, ARM DSTREAM — standard JTAG probes often lack trace bandwidth |
| Trace port on board | Not all ADP boards expose TPIU pins; check schematic for MIPI STP or parallel trace header |
| Trace decode license | ETM raw packets need instruction decode against your exact binary — symbols required |
| BSP trace enable | Some production BSPs disable ETM at boot via debug policy |
Linux Kernel Integration
Section titled “Linux Kernel Integration”On the AAOS side, CoreSight integrates with the Linux perf subsystem:
# List CoreSight devicesls /sys/bus/coresight/devices/
# perf with CoreSight (platform and kernel config dependent)perf record -e cs_etm/@tmc_etf0/ -- sleep 5perf reportQNX-side trace typically goes through vendor tools (Momentics + JTAG) rather than sysfs. For hypervisor debugging, decide which guest’s binary you need symbols for before starting capture — mixing QNX and AAOS trace decode in one session requires separate symbol files.
Interface Comparison Matrix
Section titled “Interface Comparison Matrix”| Interface | Bandwidth | Intrusiveness | Works in Crashdump? | Needs Special HW? | Setup Time | Typical Use |
|---|---|---|---|---|---|---|
| UART | Low (~11.5 KB/s) | None (passive) | Yes | USB-UART adapter (~$5) | 1 minute | Boot logs, OS console, daily debug |
| JTAG | Medium | Halting (stops CPU) | Yes (with SDI) | Lauterbach/DSTREAM ($$$) | 15 minutes | Register inspect, hard crash debug |
| SWD | Medium | Halting | Yes (with SDI) | Debug probe | 10 minutes | Same as JTAG, fewer pins |
| CoreSight Trace | High (GB/s internal) | None (non-invasive) | No | Trace probe ($$$$) | 30 minutes | Performance profiling, race conditions |
Selection heuristic: Start UART. Escalate to JTAG when UART is silent or SDI is active. Add trace only when you need timing or instruction-level history without stopping execution.
UART is a security camera — watches passively, records everything it sees, never changes what happens. JTAG is a freeze-frame button — stops time, lets you examine every detail, but nothing moves while you look. CoreSight trace is a flight recorder — captures everything at full speed; you analyze the recording later.
UART = conversation (text logs). JTAG = brain surgery (CPU halt/step). Trace = surveillance camera (non-intrusive recording).
Memorization trick: UART = Universal, always there. JTAG = Just halted everything. Trace = Total capture, zero halt.
Debug Policy and Fuses
Section titled “Debug Policy and Fuses”Hardware debug is not a software toggle on production automotive boards. Qualcomm eFuses permanently configure debug policy at manufacturing time.
Key Fuse Bits
Section titled “Key Fuse Bits”| Fuse / Policy | Effect When Blown (Closed) |
|---|---|
JTAG_DISABLE |
DAP locked — no JTAG/SWD attach |
ALL_DEBUG_DISABLE |
Broad debug lockdown — JTAG, some trace, debug auth paths |
DEBUG_POLICY_OVERRIDE |
Enables temporary re-enable via signed debug certificate (OEM-controlled) |
Open fuse (development ADP): UART + JTAG + trace enabled (BSP permitting). Closed fuse (production): UART usually retained; JTAG disabled; trace restricted.
Some OEM programs issue a signed debug certificate that temporarily re-enables JTAG via DEBUG_POLICY_OVERRIDE — requires fuse support, OEM cert matched to SOC ID, and TRACE32 with Qualcomm pack. Without all three, a fuse-closed board stays closed.
Fuse State vs Interface Availability
Section titled “Fuse State vs Interface Availability”| Fuse State | UART | JTAG / SWD | CoreSight Trace | Crashdump |
|---|---|---|---|---|
| Open (dev ADP) | Yes | Yes | Yes (if exposed) | Yes (policy permitting) |
| Closed (production) | Usually yes | No | Restricted / No | Policy-dependent |
| Closed + debug cert | Yes | Yes (temporary) | Policy-dependent | Yes |
flowchart TD
START["Can I use JTAG?"]
FUSE{"Check fuse state"}
OPEN["Open (dev fuse)\n→ Yes, JTAG available"]
CLOSED{"Closed (production fuse)"}
OVERRIDE{"Debug policy override\nenabled?"}
CERT{"Have signed debug\ncertificate?"}
YES["Yes — load cert in TRACE32\n→ JTAG temporarily enabled"]
NO["No — JTAG permanently disabled\nUse UART + crashdump instead"]
START --> FUSE
FUSE -->|"Open"| OPEN
FUSE -->|"Closed"| CLOSED
CLOSED --> OVERRIDE
OVERRIDE -->|"No"| NO
OVERRIDE -->|"Yes"| CERT
CERT -->|"Yes"| YES
CERT -->|"No"| NO
Software can also restrict debug without fuses — a production BSP may disable debug UART in device tree or set debug_policy=0 in boot config. Always check both fuse state and BSP variant (debug vs production).
UART setup checklist — run this at the start of every bench session:
- Power off board before connecting UART cable.
- Connect GND first, then TX/RX (crossover: adapter TX → board RX).
- Identify serial device:
- Linux:
ls /dev/ttyUSB*ordmesg | tailafter plug-in - macOS:
ls /dev/cu.usb*
- Linux:
- Open terminal at 115200 8N1, no flow control.
- Start log capture immediately:
Terminal window picocom -b 115200 /dev/ttyUSB0 | tee -a uart_$(date +%Y%m%d_%H%M%S).log - Power on board — confirm PBL banner within 2 seconds.
- Mark timestamps in your notes when changing boot mode (EDL entry, fastboot flash, OTA trigger).
Rule: Always tee UART to a timestamped log file. The one time you don’t is when the intermittent crash reproduces.
Beginner thinks JTAG is just for programming flash chips. Reality: it’s a full CPU debug interface — halt/step execution, inspect registers and memory, set hardware breakpoints, and capture CoreSight trace. Programming is one use case; post-mortem crash analysis and live debugging are the daily ones.
If JTAG stops connecting on a board that used to work, check three things in order:
- Is the board powered on? JTAG needs target power — the probe does not power the SoC.
- Did someone flash a production BSP? Software debug disable in device tree or boot policy blocks DAP even on fuse-open boards.
- Were fuses blown? Permanent disable — no software workaround without a debug policy override certificate.
Number 3 is irreversible on that unit. If fuse-closed, stop trying JTAG and pivot to UART + crashdump analysis.
Deep Dive
ARM debug architecture versions define what the DAP, breakpoints, and trace macrocells can do. Qualcomm implements these across the Kryo clusters on SA8155P and SA8295P with different CoreSight generations.
| Generation | SA8155P | SA8295P | Key Differences |
|---|---|---|---|
| CoreSight | v2 architecture | v3 architecture | v3 adds improved funnel routing, larger ETF buffers, better multi-core synchronization |
| Debug (ARMv8-A) | v8-A Debug architecture | v8-A Debug architecture | Self-hosted debug, OS-aware breakpoints, reduced invasive debug in secure world |
| ETM version | ETMv4.x class | ETMv4.x class (expanded) | More trace bandwidth, better timestamp correlation across cores |
What changed from CoreSight v2 (SA8155P) to v3 (SA8295P):
- Larger on-chip trace buffers (ETF) — longer capture windows before overflow, critical for intermittent automotive bugs.
- Improved cross-triggering — one core’s breakpoint can trigger trace on another core (essential for QNX/AAOS inter-VM race debugging).
- Better integration with system memory trace (ETR → DDR) — store more trace in DDR when TPIU is not wired, at the cost of memory bandwidth.
- Stricter secure-world gating — TrustZone can lock ETM for secure cores independently; automotive programs often restrict trace in production fused builds.
Practical impact: Scripts and trace decode profiles built for SA8155P do not always transfer cleanly to SA8295P. Update TRACE32/QTI packs when moving between generations. For day-to-day work, the user-visible difference is trace buffer depth and multi-core correlation — not the basic JTAG halt/step workflow, which remains the same DAP model.
Page 5.6 (BSP) configures UART and JTAG enablement in device tree — stdout-path, qcom,geni-debug-uart, and debug policy nodes. Page 8.4 (secure boot) explains fuse blowing and why production boards restrict JTAG. Page 10.1 (debug bench) maps physical connector pinouts to these interfaces. Page 10.2 (boot modes) lists which interfaces work in EDL, normal HLOS, crashdump, and SDI. Page 10.4 (software debug tools) covers TRACE32, OpenOCD, perf, and QNX Momentics — the host-side tools that speak these hardware protocols.
Check Your Understanding
1. What is the role of the ETM (Embedded Trace Macrocell) in CoreSight?
Recall2. SWD provides the same DAP capabilities as JTAG but uses how many primary data/clock wires?
Recall3. UART shows garbage characters after a BSP flash. What should you try first?
Applied4. Boot hangs with zero UART output after power-on. PBL never prints. Which debug interface should you use next?
Applied5. A production-fused SA8295P board has JTAG_DISABLE blown. Your team has no OEM debug certificate. Which statement is true?
SynthesisConnects to: Module 8 — Secure Boot
6. You need non-invasive instruction-level history on two Kryo cores during a QNX/AAOS race condition. Trace Funnel and TPIU are wired on the ADP. Which CoreSight path and host tool fit?
SynthesisConnects to: Module 6 — Kernel Internals
- ARM CoreSight Architecture Specification — Authoritative reference for ETM, ETF, ETR, funnel, and TPIU components that this page maps to Kryo cluster trace on SA8155P/SA8295P.
- ARM Debug Interface Architecture (ADI) — Defines the DAP, JTAG/SWD transport, and halt/step/register access model that TRACE32 and OpenOCD use under the hood.
- IEEE 1149.1 — Standard Test Access Port and Boundary-Scan Architecture — The JTAG standard governing TDI/TDO/TMS/TCK signaling on the 20-pin ARM debug header.
- SEGGER — J-Link Debug Probe Wiki — Practical SWD/JTAG wiring, voltage levels, and connection troubleshooting for two-wire and four-wire debug setups.
- OpenOCD User’s Guide — Open-source debugger documentation covering target configuration, DAP attach, and basic halt/memory inspect when commercial probes are unavailable.
- Lauterbach — ARM Debug and Trace — Product and documentation hub for TRACE32 ARM support, including Qualcomm automotive scripts and multi-core core-selection workflows.
- Linux Kernel — perf and CoreSight — Kernel documentation for CoreSight
perfintegration on the AAOS guest, complementing the on-target trace commands shown on this page. - QNX Momentics IDE — QNX remote debug and System Profiler tooling that pairs with JTAG and
qconnfor kernel trace analysis on the hypervisor host side.