Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: GlasgowEmbedded/glasgow
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: b87a90c31152
Choose a base ref
...
head repository: GlasgowEmbedded/glasgow
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 63158ccd8334
Choose a head ref
  • 2 commits
  • 2 files changed
  • 1 contributor

Commits on Nov 5, 2020

  1. cli: make horrifying formatting regexps even more horrifying.

    Before this commit, lists weren't formatted, which was quite ugly
    with list items longer than ~70 characters. After this commit, list
    items are reflowed and their indentation is normalized.
    whitequark committed Nov 5, 2020
    Copy the full SHA
    18a58e9 View commit details
  2. applet.interface.jtag_probe: clarify enumerate-ir documentation.

    Also, lower log level for DR[?] to WARN since it is as noncompliant
    as DR[0] and neither of these results usually indicates a problem.
    whitequark committed Nov 5, 2020
    Copy the full SHA
    63158cc View commit details
Showing with 38 additions and 26 deletions.
  1. +28 −19 software/glasgow/applet/interface/jtag_probe/__init__.py
  2. +10 −7 software/glasgow/cli.py
47 changes: 28 additions & 19 deletions software/glasgow/applet/interface/jtag_probe/__init__.py
Original file line number Diff line number Diff line change
@@ -888,31 +888,40 @@ def add_interact_arguments(cls, parser):

p_scan = p_operation.add_parser(
"scan", help="scan JTAG chain and attempt to identify devices",
formatter_class=parser.formatter_class,
description="""
Reset the JTAG TAPs and shift IDCODE or BYPASS register values out to determine
the count and (if available) identity of the devices in the scan chain.
""")

p_enumerate_ir = p_operation.add_parser(
"enumerate-ir", help="use heuristics to enumerate JTAG IR values (DANGEROUS)",
"enumerate-ir", help="(DANGEROUS) use heuristics to enumerate JTAG IR values",
formatter_class=parser.formatter_class,
description="""
THIS COMMAND CAN HAVE POTENTIALLY DESTRUCTIVE CONSEQUENCES.
IEEE 1149.1 requires that any unimplemented IR value select the BYPASS DR.
By exploiting this, and measuring DR lengths for every possible IR value,
we can discover DR lengths for every IR value.
Note that discovering DR length requires going through Capture-DR and Update-DR
states. While we strive to be as unobtrustive as possible by shifting the original
DR value back after we discover DR length, there is no guarantee that updating DR
with the captured DR value is side effect free. As such, this command can potentially
have UNPREDICTABLE side effects that, due to the nature of JTAG, can permanently
damage your target. Use with care.
Note that while unimplemented IR values are required to select the BYPASS DR,
in practice, many apparently (from the documentation) unimplemented IR values
would actually select reserved DRs instead, which can lead to confusion. In some
cases they even select a constant 0 level on TDO!
THIS COMMAND CAN PERMANENTLY DAMAGE DEVICE UNDER TEST.
IEEE 1149.1 requires every unimplemented IR value to select the BYPASS DR.
By selecting every possible IR value and measuring DR lengths, it is possible to
discover IR values that definitively correspond to non-BYPASS DRs.
Due to the design of JTAG state machine, measuring DR length requires going
through Capture-DR and Update-DR states for instructions that may have
IRREVERSIBLE or UNDEFINED behavior. Although this command updates the DR with
the data just captured from it, IEEE 1149.1 does not require this operation
to be idempotent. Additionally, many devices are not strictly compliant and
in practice may perform IRREVERSIBLE or UNDEFINED actions during operations
that IEEE 1149.1 requires to be benign, such as selecting an unimplemented
instruction, or shifting into DR. USE THIS COMMAND AT YOUR OWN RISK.
DR length measurement can have one of the following four results:
* DR[n], n > 1: non-BYPASS n-bit DR.
* DR[1]: (likely) BYPASS or (less likely) non-BYPASS 1-bit DR.
This result is not shown because most IR values correspond to DR[1].
* DR[0]: TDI connected directly to TDO.
This is not allowed by IEEE 1149.1, but is very common in practice.
* DR[?]: (commonly) no connection to TDO or (less commonly) complex logic
connected between TDI and TDO that is active during Shift-DR.
This is not allowed by IEEE 1149.1, but is common in practice.
""")
p_enumerate_ir.add_argument(
"tap_indexes", metavar="INDEX", type=int, nargs="+",
@@ -997,7 +1006,7 @@ async def interact(self, device, args, jtag_iface):
dr_length = await tap_iface.scan_dr_length(max_length=args.max_dr_length,
zero_ok=True)
if dr_length is None:
level = logging.ERROR
level = logging.WARN
dr_length = "?"
elif dr_length == 0:
level = logging.WARN
17 changes: 10 additions & 7 deletions software/glasgow/cli.py
Original file line number Diff line number Diff line change
@@ -50,16 +50,19 @@ def filler(match):
if text.startswith("::"):
return text[2:]

list_match = re.match(r"(\s*)\*", text)
list_match = re.match(r"(\s*)(\*.+)", text, flags=re.S)
if list_match:
return text

text = textwrap.fill(text, width,
initial_indent=indent,
subsequent_indent=indent)
text = re.sub(r"(\S)\s+(\S)", r"\1 \2", list_match[2])
text = textwrap.fill(text, width,
initial_indent=indent + " ",
subsequent_indent=indent + " ")
else:
text = textwrap.fill(text, width,
initial_indent=indent,
subsequent_indent=indent)

text = re.sub(r"(\w-) (\w)", r"\1\2", text)
text = text + (match[2] or "")
text = re.sub(r"(\w-) (\w)", r"\1\2", text)
return text

text = textwrap.dedent(text).strip()