Skip to content

Update Python Debug Modules and fix Virtual Timer clock issue #61

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 27 commits into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
cbffb82
[ot] scripts/opentitan: log.py: remove duplicate handlers
rivos-eblot Apr 10, 2024
ad2c6fe
[ot] scripts/opentitan: move SPDX license identifier to the first lines.
rivos-eblot Apr 10, 2024
392e796
[ot] scripts/opentitan: pyot.py: detect and report no test to execute.
rivos-eblot Apr 11, 2024
7347976
[ot] scripts/opentitan: jtag.py: use caches to speed up transitions
rivos-eblot Apr 9, 2024
6b5ea53
[ot] scripts/jtag: bitbang.py optimize comm management
rivos-eblot Apr 11, 2024
3bbab87
[ot] scripts/opentitan: lcdmi.py: remove an invalid line
rivos-eblot Apr 10, 2024
34fbdf8
[ot] scripts/opentitan: move HexInt into a dedicated module.
rivos-eblot Apr 10, 2024
3c55b14
[ot] scripts/opentitan: misc.py: add a dump buffer debug function.
rivos-eblot Apr 11, 2024
fb2578a
[ot] scripts/opentitan: factorize ElfBlob utility into a module
rivos-eblot Apr 10, 2024
a8ce0e1
[ot] scripts/opentitan: fix argument parser description message.
rivos-eblot Apr 10, 2024
bb80f0a
[ot] scripts/opentitan: create a small Debug Module to test RISC-V DM
rivos-eblot Apr 9, 2024
05bb726
[ot] scripts/opentitan: add a Python module & script to exercise RV DM.
rivos-eblot Apr 11, 2024
1531c24
[ot] scripts/opentitan: dm.py: add word memory accessors
rivos-eblot Apr 10, 2024
f696692
[ot] scripts/opentitan: otptool.py: move utility functions to ot.util…
rivos-eblot Apr 11, 2024
71b6c2a
[ot] scripts/opentitan: misc.py: update and fix dump_buffer
rivos-eblot Apr 11, 2024
d81e9bc
[ot] scripts/opentitan: otptool.py: split into front-end and modules
rivos-eblot Apr 11, 2024
57bee6f
[ot] scripts/opentitan: create a new tool to access OTP controller ov…
rivos-eblot Apr 11, 2024
e23d08f
[ot] hw/opentitan: ot_rom_ctrl: add a trace when no ROM image is defined
rivos-eblot Apr 15, 2024
2390d79
[ot] hw/opentitan: ot_rom_ctrl: reduce trace messages for valid requests
rivos-eblot Apr 16, 2024
dd976f5
[ot] hw/opentitan: ot_aon_timer: add a trace when setting watchdog
rivos-eblot Apr 16, 2024
0bb0f1e
[ot] hw/opentitan: ot_ast_dj: fix virtual clock type
rivos-eblot Apr 15, 2024
54f8fbc
[ot] hw/opentitan: ot_common: use VIRTUAL timer, not VIRTUAL_RT
rivos-eblot Apr 16, 2024
b36e0eb
[ot] hw/opentitan: ot_timer: add OT identifier and update trace name
rivos-eblot Apr 16, 2024
9aad698
[ot] scripts/opentitan: improve RV-DM implementation and fix a parser…
rivos-eblot Apr 15, 2024
425e14c
[ot] scripts/jtag: remove useless APIs
rivos-eblot Apr 15, 2024
5637af3
[ot] scripts/opentitan: dtm.py, otpdm.py: report default settings
rivos-eblot Apr 15, 2024
637ee7b
[ot] docs/opentitan: add a JTAG troubleshooting section.
rivos-eblot Apr 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 136 additions & 0 deletions docs/opentitan/dtm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# `dtm.py`

`dtm.py` checks that the JTAG/DTM/DM stack is up and running and demonstrates how to use the
Debug Module to access the Ibex core.

## Usage

````text
usage: dtm.py [-h] [-H HOST] [-P PORT] [-Q] [-l IR_LENGTH] [-b BASE] [-I] [-c]
[-C MISA_CHECK] [-x] [-X] [-a ADDRESS] [-m {read,write}]
[-s SIZE] [-f FILE] [-e ELF] [-v] [-d]

Debug Transport Module tiny demo

options:
-h, --help show this help message and exit

Virtual machine:
-H HOST, --host HOST JTAG host (default: localhost)
-P PORT, --port PORT JTAG port, default: 3335
-Q, --no-quit do not ask the QEMU to quit on exit

DMI:
-l IR_LENGTH, --ir-length IR_LENGTH
bit length of the IR register
-b BASE, --base BASE define DMI base address

Info:
-I, --info report JTAG ID code and DTM configuration
-c CSR, --csr CSR read CSR value from hart
-C CSR_CHECK, --csr-check CSR_CHECK
check CSR value matches

Actions:
-x, --execute update the PC from a loaded ELF file
-X, --no-exec does not resume hart execution

Memory:
-a ADDRESS, --address ADDRESS
address of the first byte to access
-m {read,write}, --mem {read,write}
access memory using System Bus
-s SIZE, --size SIZE size in bytes of memory to access
-f FILE, --file FILE file to read/write data for memory access
-e ELF, --elf ELF load ELF file into memory
-F, --fast-mode do not check system bus status while transfering

Extras:
-v, --verbose increase verbosity
-d, --debug enable debug mode
````

### Arguments

* `-a` specify the memory address where data is loaded or stored. Useful with the `--mem` option.
See also the `--size` option. Note that only 32-bit aligned addresses are supported for now.

* `-b` specify the DMI base address for the RISC-V Debug Module

* `-C` compare a CSR value to the specified value. Requires option `--csr`.

* `-c` read and report a CSR from the Ibex core.

* `-d` only useful to debug the script, reports any Python traceback to the standard error stream.

* `-e` specify an ELF32 application file to upload into memory. See also the `--exec` option.

* `-F` assume System Bus can cope with received data pace. This feature increases transfer data
rate by bypassing SB status check. However it may cause the transfer to fail in case System Bus
becomes busy while data are transfered.

* `-H` specify the address of the QEMU VM.

* `-I` report the JTAG ID code and the DTM configuration.

* `-l` specify the length of the TAP instruction register length.

* `-m <read|write>` specify a memory operation to perform. See also `--address`, `--size` and
`--file` options. With `read` operation, if no `--file` is specified, the content of the selected
memory segment is dumped to stdout, with a similar format as the output of `hexdump -C`. If a file
is supplied, the content of the segment is written as binary data into this file. With `write`
operation, `--file` argument is mandatory. The content of the binary file is copied into the
memory, starting at the `--address`. See also the `--elf` option for uploading applications.

* `-P` specify the TCP port of the JTAG server in the QEMU VM, should match the port part of `-jtag`
option for invoking QEMU.

* `-Q` do not send QEMU a request for termination when this script exits.

* `-s` specify the number of bytes to read from or write to memory. Useful with the `--mem` option.
See also the `--address` option. This option may be omitted for the `write` memory operation, in
which case the size of the specified file is used. Note that only sizes multiple of 4-byte are
supported for now.

* `-v` can be repeated to increase verbosity of the script, mostly for debug purpose.

* `-X` do not attempt to resume normal execution of the hart once DTM operation have been completed.
This can be useful for example when the QEMU VM is started with `-S` and no application code has
been loaded in memory: once the DTM operations are completed, the default behavior is to resume
the hart execution, would start execution code from the current PC and cause an immediate
exception. The `-x` option can nevertheless be executed, as it is the last action that the script
performs.

* `-x` execute the loaded ELF application from its entry point. Requires the `--elf` option.
Application is executed even with `-X` defined.

### Examples

Running QEMU VM with the `-jtag tcp::3335` option:

* Retrieve JTAG/DTM/DM information and `mtvec` CSR value
````sh
./scripts/opentitan/dtm.py -I -c mtvec
````

* Check that the MISA CSR matches the expected Ibex core value:
````sh
./scripts/opentitan/dtm.py -c misa -C 0x401411ad
````

* Load (fast mode) and execute an application
````sh
./scripts/opentitan/dtm.py -e .../helloworld -x -F
````

* Dump a memory segment to stdout
````sh
./scripts/opentitan/dtm.py -m read -a 0x1000_0080 -s 0x100
````

* Upload a file into memory and leave the Ibex core halted
````sh
./scripts/opentitan/dtm.py -m write -a 0x1000_0000 -f file.dat -X

````

51 changes: 48 additions & 3 deletions docs/opentitan/jtag-dm.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ dispatches requests to Debug Module depending on the received DMI address.
See also [JTAG mailbox](jtagmbx.md) and [Life Controller](lc_ctrl_dmi.md) for other Debug Modules.

```
+----------------+
| Host (OpenOCD) |
+----------------+
+--------------------------+
| Host (OpenOCD or Python) |
+--------------------------+
|
| TCP connection ("bitbang mode")
|
Expand Down Expand Up @@ -118,3 +118,48 @@ A basic `$HOME/.gdbinit` as the following should connect GDB to the running Open
```
target remote :3333
```

## Communicating with JTAG server using Python

`scripts/opentitan/ot` directory contains Python modules that provide several APIs to test the
JTAG/DTM/DM stack.

A demo application is available from [`scripts/opentitan/dtm.py`](dtm.md) that can report basic
information about this stack and demonstrate how to use the Debug Module to access the Ibex core.

The [`scripts/opentitan/otpdm.py`](otpdm.md) also use the same stack to access the cells of the OTP
controller.

### Troubleshooting [#troubleshooting]

A common issue with initial JTAG configuration is to use the wrong Instruction Register length.
The IR length depends on the actual implementation of the TAP controller and therefore may be
different across HW implementations, here across OpenTitan instantiations.

Unfortunately, there is no reliable way to automatically detect the IR length, this needs to be
a setting that should be provided to the JTAG tool. Scripts in `scripts/opentitan` use the `-l` /
`--ir-length` option to specify the IR length. The default value may be obtained with the `-h`
option, which is IR length = 5 bits for default EarlGrey and Darjeeling machines.

Whenever the wrong IR length is specified, or the default IR length is used with a HW/VM machine
that uses a non-default length, the first instruction that is stored in the TAP instruction register
is misinterpreted, which may cause different errors with the same root cause: a wrong IR length
setting.

It is recommended to query the DMI address bits with for example [`scripts/opentitan/dtm.py`](dtm.md)
which is a basic command that needs a valid IR length setting to complete. Use `dtm.py -I` to query
some low-level information from the remote peer.

It should report something like:
````
IDCODE: 0x11cdf
DTM: v0.13, 12 bits
````

* If the DTM bit count is stuck to 0, the IR length is likely wrong,
* If an error message such as `Invalid reported address bits` is returned, the IR length is likely
wrong.

Another common issue is to use a machine with multiple Debug Modules but fail to specify its base
address. The default DMI base address is always `0x0`. Use `-b` / `--base` option to select the
proper Debug Module base address.
4 changes: 4 additions & 0 deletions docs/opentitan/jtagmbx.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,3 +246,7 @@ Note: `devproxy.py` needs to be found within the Python path, using for example
```sh
exprot PYTHONPATH=${QEMU_SOURCE_PATH}/scripts/opentitan
```

### Troubleshooting

See the [Troubleshooting](jtag-dm.md#troubleshooting) section for details.
4 changes: 4 additions & 0 deletions docs/opentitan/lc_ctrl_dmi.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,7 @@ lc_ctrl = LifeCycleController(dtm, 0x3000 >> 2)

# See LifeCycleController for LC controller communication API
````

### Troubleshooting

See the [Troubleshooting](jtag-dm.md#troubleshooting) section for details.
139 changes: 139 additions & 0 deletions docs/opentitan/otpdm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# `dtm.py`

`otpdm.py` gives access to the OTP Controller through the JTAG/DTM/DM interface.

## Usage

````text
usage: otpdm.py [-h] [-H HOST] [-P PORT] [-Q] [-l IR_LENGTH] [-b BASE] [-j HJSON] [-a ADDRESS]
[-p PARTITION] [-i ITEM] [-L] [-r] [-w WRITE] [-D] [-v] [-d]

OTP controller access through the RISC-V Debug Module

options:
-h, --help show this help message and exit

Virtual machine:
-H HOST, --host HOST JTAG host (default: localhost)
-P PORT, --port PORT JTAG port, default: 3335
-Q, --no-quit do not ask the QEMU to quit on exit

DMI:
-l IR_LENGTH, --ir-length IR_LENGTH
bit length of the IR register
-b BASE, --base BASE define DMI base address

OTP:
-j HJSON, --otp-map HJSON
input OTP controller memory map file
-a ADDRESS, --address ADDRESS
base address the OTP controller, default: 0x30130000
-p PARTITION, --partition PARTITION
select a partition
-i ITEM, --item ITEM select a partition item
-L, --list list the partitions and/or the items
-r, --read read the value of the selected item
-w WRITE, --write WRITE
write the value to the selected item
-D, --digest show the OTP HW partition digests

Extras:
-v, --verbose increase verbosity
-d, --debug enable debug mode````
````

### Arguments

* `-a` specify an alternative address for the OTP controller on the OT bus.

* `-b` specify the DMI base address for the RISC-V Debug Module.

* `-D` show partition digest(s). If no parition is selected (see option `-p`), the digest of all
partitions are shown; otherwise the digest of the selected partition is shown. Requires
option `-j`.

* `-d` only useful to debug the script, reports any Python traceback to the standard error stream.

* `-H` specify the address of the QEMU VM.

* `-i` select a specific item from a partition. See option `-L` to get a list of valid item names
for the currently selected partition. Requires `-p` option.

* `-j` specify the path to the OpenTitan OTP controller map, _e.g._ `otp_ctrl_mmap.hjson`.

* `-L` list the names of the partitions if no partition is selected (see option `-p`). If option
`-p` is used, list the names of the selected partition items if no item is selected (see
option `-i`). If option `-i` is used, show all the properties of the selected item.

* `-l` specify the length of the TAP instruction register length.

* `-P` specify the TCP port of the JTAG server in the QEMU VM, should match the port part of `-jtag`
option for invoking QEMU.

* `-p` select a partition using its name. See option `-L` to get a list of valid partition names.
Requires option `-j`.

* `-Q` do not send QEMU a request for termination when this script exits.

* `-r` load and show the value of the selected item. Requires options `-p` and `-i`.

* `-v` can be repeated to increase verbosity of the script, mostly for debug purpose.

* `-w` store the value into the selected item. Requires options `-p` and `-i`. The value should be
specifed as an hexadecimal or decimal integer for item whose size is less or equal to 8
bytes. For larger items the value should be specified as a sequence of hexa-encoded bytes.

### Examples

Running QEMU VM with the `-jtag tcp::3335` option:

* List all supported partitions
````sh
./scripts/opentitan/otpdm.py -j .../otp_ctrl_mmap.hjson -L
````

* List all supported items of a partition
````sh
./scripts/opentitan/otpdm.py -j .../otp_ctrl_mmap.hjson -p HW_CFG1 -L
````

* List all properties of an item
````sh
./scripts/opentitan/otpdm.py -j .../otp_ctrl_mmap.hjson -p HW_CFG1 -i EN_SRAM_IFETCH -L
````

* Show all digests
````sh
./scripts/opentitan/otpdm.py -j .../otp_ctrl_mmap.hjson -D
````

* Show the digest of a single partition (parsable output)
````sh
./scripts/opentitan/otpdm.py -j .../otp_ctrl_mmap.hjson -p HW_CFG1 -D
````

* Read the value of an item along with the item properties
````sh
./scripts/opentitan/otpdm.py -j .../otp_ctrl_mmap.hjson -p HW_CFG1 -i EN_SRAM_IFETCH -r
````

* Read the value of an item along (parsable output)
````sh
./scripts/opentitan/otpdm.py -j .../otp_ctrl_mmap.hjson -p HW_CFG1 -i EN_SRAM_IFETCH -r
````

* Write the value of an integer item
````sh
./scripts/opentitan/otpdm.py -j .../otp_ctrl_mmap.hjson -p HW_CFG1 -i EN_SRAM_IFETCH -w 0xff
````

* Write the value of a long item
````sh
./scripts/opentitan/otpdm.py -j .../otp_ctrl_mmap.hjson -p HW_CFG0 -i DEVICE_ID \
-w 4c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e73
````

### Troubleshooting

See the [Troubleshooting](jtag-dm.md#troubleshooting) section for details.

5 changes: 4 additions & 1 deletion docs/opentitan/pyot.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ Files:
-f RAW, --flash RAW embedded Flash image file
-x file, --exec file rom extension or application
-b file, --boot file bootloader 0 file
-Z, --zero do not error if no test can be executed

Execution:
-R, --summary show a result summary
Expand Down Expand Up @@ -144,7 +145,9 @@ This tool may be used in two ways, which can be combined:
* `-b` / ` --boot` specify a bootloader 0 file that can be added to the flash image file when
a ROM extension file is specified with the `-x` option. This option is mutually exclusive with
the `-f` option.

* `-Z`, `--zero` do not report an error if no test can be executed with the specified filters and
detected test applications. Default behavior is to report an error should such a condition arise,
as it likely comes from a misconfiguration or build issue.

## Configuration file

Expand Down
4 changes: 4 additions & 0 deletions docs/opentitan/tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ directory to help with these tasks.

## Companion file management

* [`otpdm.py`](otpdm.md) can be used to access the OTP Controller over a JTAG/DTM/DM link. It reads
out partition's item values and can update those items.
* [`otptool.py`](otptool.md) can be used to generate an OTP image from a OTP VMEM file and can be
used to decode (some of the) encoded data in the OTP image.
* [`flashgen.py`](flashgen.md) can be used to generate a flash image with either a ROM_EXT and BL0
Expand All @@ -31,6 +33,8 @@ directory to help with these tasks.
develop the machine itself.
* `devproxy.py` is a Python module that provides an API to remote drive the [DevProxy](devproxy.md)
communication interface.
* [`dtm.py`](dtm.md) is a tiny Python script that can be used to check the JTAG/DTM/DM stack is
up and running and demonstrate how to use the Debug Module to access the Ibex core.
* [`gdbreplay.py`](gdbreplay.md) is a basic GDB server that can be used to replay Ibex execution
stream from a QEMU execution trace.
* [`gpiodev.py`](gpiodev.md) is a tiny script to run regression tests with GPIO device.
Expand Down
1 change: 1 addition & 0 deletions hw/opentitan/ot_aon_timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ static void ot_aon_timer_rearm_wdog(OtAonTimerState *s, bool reset_origin)
} else {
int64_t delta = ot_aon_timer_ticks_to_ns(s, 0u, threshold - count);
int64_t next = ot_aon_timer_compute_next_timeout(s, now, delta);
trace_ot_aon_timer_set_wdog(now, next);
timer_mod(s->wdog_timer, next);
}

Expand Down
Loading
Loading