GitHub - oxidecomputer/humility: Debugger for Hubris (original) (raw)

Humility

Humility is the debugger for Hubris.

Guiding principles

Production disposition

Hubris is the artifact that actually runs, and it must be allowed to be optimized in terms of size, space, and run-time; in as much as contortions are required for debuggability, they should be borne by Humility, not Hubris. As a concrete example of this, Humility operates exclusively on release builds of Hubris, relying on (unloaded) DWARF information in the binaries to make sense of the system.

Hubris-specific

Humility is Hubris-specific: it is not trying to be a generic in situ debugger, but rather specifically focused on debugging Hubris-based systems. Humility is therefore willing to encode Hubris-specific concepts like archives and tasks.

Microcontroller-specific

Debuggers must cut through abstractions, which often requires knowledge of underlying implementation detail. For Humility, this means being willing to take advantage of microcontroller-specific debug facilities where applicable. While Hubris may make decisions in the name of greater portability, Humility will generally make decisions to maximize debuggability, even where these facilities are highly specific to a particular MCU.

Device-specific

Humility is unafraid to offer device-specific functionality where that functionality is useful for system debuggability. (For example,humility i2c functions as an I2C analyzer.) That said, all device interaction uses Hubris as a proxy to actually communicate with the devices themselves (e.g., HIF); Humility does not seek to create second I/O path.

Pragmatic

Humility seeks to be useful, and therefore seeks to offer all manners of debugging: in situ, postmortem, dynamic instrumentation, static instrumentation, etc.

Operation

Humility operates by specifying a subcommand. There are options that are Humility-wide (that is, applying to every subcommand), as well as options that are specific to particular subcommands.

Probe

Humility needs to have some way of extracting information and/or controlling the microcontroller running Hubris. This is done through some variant of a debug probe, a separate microcontroller that speaks to debug-specific functionality on the target microcontroller.

For most evaluation boards, this debug probe is available on the board, and is connected to a host via USB, e.g. ST's STLink/V2 on the STM32F407 Discovery or the LPC-Link2 present on the LPCXpresso55S69. (On the Gemini board, there are two SWD headers, one for the LPC55S28 and the other for the STM32H753.)

While Humility allows for direct attachment to an on-chip debugger, doing so precludes other connections (from, for example, OpenOCD), making it too disruptive to development workflows. To allow for easier development workflows, Humility also has the option to attach via OpenOCD.

The debug probe to use is specified to Humility via the -p option (long form --probe) or the HUMILITY_PROBE environment variable, which can have the following values:

Archive

Many Humility commands require the complete Hubris archive. This is a ZIP archive created by the build process, and includes all binaries as well as theapp.toml file used to configure the Hubris archive. The archive can be found in the target for Hubris, and will end with (.zip), e.g.:/path/to/hurbis/target/demo-stm32h753-nucleo/dist/default/build-demo-stm32h753-nucleo.zip. The Hubris archive is specified via the -a option or the HUMILITY_ARCHIVEenvironment variable.

In the Humility examples in this documentation, unless otherwise specified, the archive will be assumed to be set via -a or HUMILITY_ARCHIVE.

Dump

Many Humility commands are able to operate postmortem on a Hubris dump, an ELF core file generated by the humility dump command. Dumps are offered in lieu of a probe and an archive and specified via the -d option (long form --dump) or the HUMILITY_DUMP environment variable.

Network

On Hubris systems that are so equipped, Humility can operate over a network in lieu of a dump or probe. When operating over a network, the archive must always be provided via -a, as well as the IP address of the target via-i (long form --ip) or the HUMILITY_IP environment variable. Note that not all commands can operate over the network, including (but not limited to) any command that stops the target or reads memory directly.

Environment

On machines that have several different connected Hubris targets, Humility can become thorny to manage. To aid this, Humility allows for environments: JSON files that define how targets can be reached and auxiliary operations that can be performed upon them. The environment file is specified via either the --environment argument or via the HUMILITY_ENVIRONMENT environment variable; a specific target within the environment is specified via the--target argument or via the HUMILITY_TARGET environment variable.

Environment file structure

The environment file contains a JSON object in which each key represents a target. The members of each target object must include probe and archive, which have the same meaning as the probe and archive as provided via the command line. For example:

{ "lucky": { "probe": "0483:374e:002A00174741500520383733", "archive": "/gimlet/hubris/archives/lucky/build-gimlet.zip" }, "sweaty": { "probe": "0483:374e:000D00184741500520383733", "archive": "/gimlet/hubris/archives/sweaty/build-gimlet.zip" }, "grimey": { "probe": "0483:374e:003400185553500820393256", "archive": "/gimlet/hubris/archives/grimey/build-gimlet.zip" } }

Some targets may require multiple archives. These can be specified by name. The archive to be used must be specified with the --archive-nameoption to humility.

{ "lucky": { "probe": "0483:374e:002A00174741500520383733", "archive": { imagea: "/gimlet/hubris/archives/lucky/build-a-gimlet.zip", imageb: "/gimlet/hubris/archives/lucky/build-b-gimlet.zip" } }, }

The above definition -- when provided via --environment orHUMILITY_ENVIRONMENT -- would allow one to (say) run humility --target grimey tasks or humility --target lucky --image-name imagea tasks. In addition to probe and archive, one may also specify associated commands in a cmds object that contains a mapping of names to commands to execute. For example:

{ "grimey": { "probe": "0483:374e:003400185553500820393256", "archive": "/gimlet/hubris/archives/grimey/build-gimlet.zip" "cmds": { "console": "/bin/sh -c "grabserial.sh $(findtty.sh grimey)"", "power": { "on": "power.sh --on grimey", "off": "power.sh --off grimey", "status": "power.sh --status grimey", } } } }

These commands can be in principle accessed by any debugging command, but thehumility exec command in particular allows one to execute a command against a specified target. (In the above example, one could execute humility --target grimey exec power.on.)

Commands

humility apptable

This is a deprecated command that allows for the display of the app table found in old Hubris archives; see humility manifest to understand the contents of an archive.

humility auxflash

Tools to interact with the auxiliary flash, described in RFD 311.

This subcommand should be rarely used; humility flash will automatically program auxiliary flash when needed.

humility bankerase

Erase flash in "erase block" size chunks (32 KiB) on the RoT.

Erase len is given in bytes and then rounded up to the nearest block size so that all pages containing the range are erased. Then the erased pages are overwritten with 0s, but only starting at the address given. In other words, if the address is given as 0x40001 and len as 512, flash will be erased from 0x40000 to 0x48000, but address 0x40000 will have value0xff, and every other byte will have value 0.

humility console-proxy

Act as a proxy for the host serial console when it is jumpered to the SP.

humility counters

humility counters reads and displays any Hubris counters (as created via the counters crate and either the counters! or counted_ringbuf!macros).

For example:

$ humility -d ./hubris.core.0 counters humility: attached to dump gimlet_seq | +---> drv_gimlet_seq_server::__RINGBUF: TOTAL VARIANT 1 Ice40Rails 1 IdentValid 1 ChecksumValid 1 Reprogram 1 Programmed 1 Programming 1 Ice40PowerGoodV1P2 1 Ice40PowerGoodV3P3 1 RailsOff 1 Ident 1 A2Status 1 A2 102 A1Status 1 CPUPresent 1 Coretype 292 A0Status 15 A0Power ...

If an argument is provided, only counters that have a name that contains the argument as a substring, or are in a task that contains the argument as a substring will be displayed. For example, to display every counter that has thermal in the name or the containing task:

$ humility -d ./hubris.core.0 counters thermal humility: attached to dump thermal | +---> task_thermal::__RINGBUF: TOTAL VARIANT 1 Start 1 ThermalMode(Auto) 3 AutoState(Boot) 2 AutoState(Running) 78 ControlPwm 2 PowerModeChanged 6 FanAdded

IPC counters

The ipc subcommand shows IPC client counters generated automatically byidol, showing the total request count for a given IPC and per-client-task breakdowns. For example:`

$ humility -d ./hubris.core.0 counters ipc` humility: attached to dump drv_gimlet_hf_api::__HOSTFLASH_CLIENT_COUNTERS fn HostFlash::get_mux() .............................................. 6 calls clients: task host_sp_comms (0 restarts) .................... = 0 ........... = 6 ok

fn HostFlash::set_mux() .............................................. 2 calls clients: task gimlet_seq (0 restarts) ....................... + 0 ........... + 1 ok task host_sp_comms (0 restarts) .................... + 0 ........... + 1 ok --- --- totals: = 0 err = 2 ok

fn HostFlash::get_dev() .............................................. 1 calls clients: task host_sp_comms (0 restarts) .................... = 0 ........... = 1 ok

drv_gimlet_seq_api::__SEQUENCER_CLIENT_COUNTERS fn Sequencer::get_state() ......................................... 2017 calls clients: task thermal (0 restarts) .......................... + 0 ........ + 1386 ok task power (0 restarts) ............................ + 0 ......... + 626 ok task host_sp_comms (0 restarts) .................... + 0 ........... + 5 ok --- ------ totals: = 0 err = 2017 ok ...

When displaying counters by IPC, substring filtering is performed on the counters variable, but not on the client task name. This allows filtering the output based on the IPC interface. For example:

$ humility -d ./hubris.core.0 counters ipc sensors humility: attached to dump task_sensor_api::__SENSOR_CLIENT_COUNTERS fn Sensor::post() ................................................ 76717 calls clients: task power (0 restarts) ............................ + 0 ....... + 50300 ok task thermal (0 restarts) .......................... + 0 ....... + 26417 ok --- ------- totals: = 0 err = 76717 ok

fn Sensor::get_reading() ......................................... 19804 calls clients: task thermal (0 restarts) ...................................... = 18101 ok

totals: = 1703 err = 18101 ok

fn Sensor::nodata() ............................................... 6225 calls clients: task power (0 restarts) ............................ + 0 ........ + 3536 ok task thermal (0 restarts) .......................... + 0 ........ + 2689 ok --- ------ totals: = 0 err = 6225 ok

Instead, to show only the IPC counters recorded by specific client tasks, use the --client argument, which will filter the output counters to those recorded in tasks whose names match the provided strings. For example, to show only IPC counters recorded by the gimlet_seq task, use:

$ humility -d ./hubris.core.0 counters ipc --client gimlet_seq humility: attached to dump drv_gimlet_hf_api::__HOSTFLASH_CLIENT_COUNTERS fn HostFlash::set_mux() .............................................. 1 calls clients: task gimlet_seq (0 restarts) ....................... = 0 ........... = 1 ok

drv_spi_api::__SPI_CLIENT_COUNTERS fn Spi::exchange() ............................................... 67580 calls clients: task gimlet_seq (0 restarts) ....................... = 0 ....... = 67580 ok

fn Spi::write() .................................................... 530 calls clients: task gimlet_seq (0 restarts) ....................... = 0 ......... = 530 ok

fn Spi::lock() ....................................................... 4 calls clients: task gimlet_seq (0 restarts) ....................... = 0 ........... = 4 ok

fn Spi::release() .................................................... 1 calls clients: task gimlet_seq (0 restarts) ....................... = 0 ........... = 1 ok

drv_stm32xx_sys_api::__SYS_CLIENT_COUNTERS fn Sys::gpio_read_input() ........................................ 16796 calls clients: task gimlet_seq (0 restarts) ....................... = 0 ....... = 16796 ok

fn Sys::gpio_set_reset() ............................................ 15 calls clients: task gimlet_seq (0 restarts) ....................... = 0 .......... = 15 ok

fn Sys::gpio_configure_raw() ........................................ 14 calls clients: task gimlet_seq (0 restarts) ....................... = 0 .......... = 14 ok

task_jefe_api::__JEFE_CLIENT_COUNTERS fn Jefe::set_state() ................................................. 5 calls clients: task gimlet_seq (0 restarts) ....................... = 0 ........... = 5 ok

task_packrat_api::__PACKRAT_CLIENT_COUNTERS fn Packrat::set_spd_eeprom() ........................................ 32 calls clients: task gimlet_seq (0 restarts) ....................... = 0 .......... = 32 ok

fn Packrat::set_mac_address_block() .................................. 1 calls clients: task gimlet_seq (0 restarts) ....................... = 0 ........... = 1 ok

fn Packrat::set_identity() ........................................... 1 calls clients: task gimlet_seq (0 restarts) ....................... = 0 ........... = 1 ok

Multiple --client arguments may be provided, to show IPCs from any of a set of client tasks.

--client may be combined with a filter matching counter variable names, to show only the calls to specific IPC interfaces from specific tasks.

humility dashboard

Provides a captive dashboard that graphs sensor values over time. (Thesensor task is required for operation; see the documentation forhumility sensors for more details.)

If -o is provided, it specifies an output file for any raw sensor data graphed by the dashboard.

humility debugmailbox

The LPC55 includes an extra access port referred to as the Debug Mailbox. This allows for running a fixed set of commands to do useful things such as forcing SWD enablement and putting the chip into ISP mode without needing to touch an external pin

$ humility debugmailbox debug Looks like a plausible debug mailbox Reset chip successfully! entering debug

$ humility debugmailbox isp Looks like a plausible debug mailbox Reset chip successfully! entered ISP mode!

humility diagnose

This subcommand provides a "firmware engineer in a can" for scanning and reporting issues in a running system. It's mostly concerned with

This is application-independent logic, so it doesn't have any visibility into things the application may think are fishy -- only general behaviors at the OS level, like faults.

humility doc

Provides detailed documentation for Humility and its commands. To get documentation on Humility, run humility doc; to get documentation for a specific command (like this one!) run humility doc and specify the command name -- and run humility --help to list all commands.

humility dump

humility dump takes a dump of the attached system, writing out an ELF core file:

$ humility dump humility: attached via ST-Link humility: core halted humility: dumping to hubris.core.0 humility: dumped 1.12MB in 24 seconds humility: core resumed

A dump file name may also be specified:

$ humility dump hubris.core.date +%s humility: attached via ST-Link humility: core halted humility: dumping to hubris.core.1600718079 humility: dumped 1.12MB in 24 seconds humility: core resumed

The resulting dump can be used with many commands (including manifest,map, readvar, and tasks) -- and need not be run on the same machine as the debugged MCU, e.g.:

$ humility -d hubris.core.0 tasks humility: attached to dump system time = 94529 ID TASK GEN PRI STATE 0 jefe 0 0 recv, notif: bit0 bit1(T+71) 1 net 1 5 recv, notif: bit0(irq61) bit2(T+213) 2 sys 0 1 recv 3 spi4_driver 0 3 recv 4 spi2_driver 0 3 recv 5 i2c_driver 0 3 recv 6 spd 0 2 notif: bit0(irq31/irq32) 7 thermal 0 5 recv, notif: bit0(T+673) 8 power 0 6 recv, notif: bit0(T+351) 9 hiffy 0 5 wait: reply from dump_agent/gen0 10 gimlet_seq 0 4 recv, notif: bit0 11 hash_driver 0 2 recv 12 hf 0 3 recv 13 update_server 0 3 recv 14 sensor 0 4 recv, notif: bit0(T+472) 15 host_sp_comms 0 7 recv, notif: bit0(irq82) bit1 16 udpecho 0 6 notif: bit0 17 udpbroadcast 0 6 notif: bit31(T+86) 18 udprpc 0 6 notif: bit0 19 control_plane_agent 0 6 recv, notif: bit0 bit1(irq37) bit2 20 sprot 0 4 notif: bit31(T+2) 21 validate 0 5 recv 22 vpd 0 4 recv 23 user_leds 0 2 recv 24 dump_agent 0 4 wait: reply from sprot/gen0 25 idle 0 8 RUNNING

humility exec

humility exec executes a command for a target within the specified environment. The environment is specified to Humility via an argument (--environment) or an environment variable (HUMILITY_ENVIRONMENT); the target is similarly specified via an argument (--target) or an environment variable (HUMILITY_TARGET). If specified via an argument, note that both the environment and target must occur before any subcommand, e.g.:

$ humility -e /path/to/env.json -t my-target exec power.on

To list available commands, use the --list option.

For more details, see the Humliity documenation on environments.

humility extract

humility extract extracts a file from either a Hubris archive or a dump. By default, the contents of the file are sent to standard output, e.g.:

$ humility -a /path/to/my/hubris-archive.zip extract README.TXT humility: extracting README.TXT to stdout This is a build archive containing firmware build artifacts.

To list all of the files in an archive, use the --list (-l) option:

$ humility -a /path/to/my/hubris-archive.zip extract --list SIZE NAME 462 README.TXT 46 git-rev 5289 app.toml 1937 chip.toml 197456 elf/task/jefe 208836 elf/task/sys 288440 elf/task/i2c_driver 309100 elf/task/spi_driver 1059092 elf/task/net 65156 elf/task/user_leds 87284 elf/task/ping 31228 elf/task/pong 178600 elf/task/udpecho 370756 elf/task/hiffy 310184 elf/task/hf 286556 elf/task/hash_driver 17612 elf/task/idle 201964 elf/task/rng_driver 555820 elf/kernel 1550 info/allocations.txt 4195 info/map.txt 632426 img/combined.srec 307060 img/combined.elf 862933 img/combined.ihex 307200 img/combined.bin 632426 img/final.srec 307060 img/final.elf 862933 img/final.ihex 307200 img/final.bin 1790 img/flash.ron 1047 debug/script.gdb 1586 debug/openocd.cfg 235 debug/openocd.gdb

Note that the file specified is treated as a substring; if the substring matches exactly one file, it will be extracted:

$ humility -d ./hubris.core.79 extract map humility: extracting info/map.txt to stdout ADDRESS END SIZE FILE 08000000 08000298 298 target/demo-stm32h753-nucleo/dist/kernel 08000298 08004420 4188 target/demo-stm32h753-nucleo/dist/kernel 08004420 08005604 11e4 target/demo-stm32h753-nucleo/dist/kernel 08005a00 08005a58 58 target/demo-stm32h753-nucleo/dist/idle 08005c00 08005e10 210 target/demo-stm32h753-nucleo/dist/pong 08005e10 08005e88 78 target/demo-stm32h753-nucleo/dist/pong 08006000 080076f4 16f4 target/demo-stm32h753-nucleo/dist/jefe 080076f4 08007c08 514 target/demo-stm32h753-nucleo/dist/jefe 08007c08 08007c08 0 target/demo-stm32h753-nucleo/dist/jefe 08008000 08009798 1798 target/demo-stm32h753-nucleo/dist/udpecho 08009798 08009b90 3f8 target/demo-stm32h753-nucleo/dist/udpecho 08009b90 08009b90 0 target/demo-stm32h753-nucleo/dist/udpecho 08010000 08014020 4020 target/demo-stm32h753-nucleo/dist/hiffy 08014020 08015134 1114 target/demo-stm32h753-nucleo/dist/hiffy 08015134 0801574c 618 target/demo-stm32h753-nucleo/dist/hiffy 08018000 08019970 1970 target/demo-stm32h753-nucleo/dist/i2c_driver 08019970 08019ff4 684 target/demo-stm32h753-nucleo/dist/i2c_driver 08019ff4 0801a300 30c target/demo-stm32h753-nucleo/dist/i2c_driver 0801c000 0801de78 1e78 target/demo-stm32h753-nucleo/dist/spi_driver 0801de78 0801e898 a20 target/demo-stm32h753-nucleo/dist/spi_driver 0801e898 0801eca4 40c target/demo-stm32h753-nucleo/dist/spi_driver 08020000 0802a554 a554 target/demo-stm32h753-nucleo/dist/net 0802a554 0802d74c 31f8 target/demo-stm32h753-nucleo/dist/net 0802d74c 0802d7dc 90 target/demo-stm32h753-nucleo/dist/net 08040000 08041ea0 1ea0 target/demo-stm32h753-nucleo/dist/hf 08041ea0 080426a8 808 target/demo-stm32h753-nucleo/dist/hf 080426a8 080426a8 0 target/demo-stm32h753-nucleo/dist/hf 08044000 08044b8c b8c target/demo-stm32h753-nucleo/dist/ping 08044b8c 08044d34 1a8 target/demo-stm32h753-nucleo/dist/ping 08044d34 08044d34 0 target/demo-stm32h753-nucleo/dist/ping 08046000 080478b4 18b4 target/demo-stm32h753-nucleo/dist/hash_driver 080478b4 08047f68 6b4 target/demo-stm32h753-nucleo/dist/hash_driver 08047f68 08047f68 0 target/demo-stm32h753-nucleo/dist/hash_driver 08048000 08048fcc fcc target/demo-stm32h753-nucleo/dist/rng_driver 08048fcc 08049474 4a8 target/demo-stm32h753-nucleo/dist/rng_driver 08049474 08049474 0 target/demo-stm32h753-nucleo/dist/rng_driver 0804a000 0804a634 634 target/demo-stm32h753-nucleo/dist/sys 0804a634 0804a67c 48 target/demo-stm32h753-nucleo/dist/sys 0804a800 0804ac0c 40c target/demo-stm32h753-nucleo/dist/user_leds 0804ac0c 0804ac7c 70 target/demo-stm32h753-nucleo/dist/user_leds 20000400 20000400 0 target/demo-stm32h753-nucleo/dist/kernel 30000000 30000000 0 target/demo-stm32h753-nucleo/dist/net

If the substring matches more than one file, the command will fail and the matching files will be displayed:

$ humility -d ./hubris.core.79 extract toml humility extract failed: "toml" matches multiple files: app.toml, stm32h7.toml

To redirect output to a particular file, use the --output (-o) option.

To dump the entire archive, leave the file unspecified. (Note that extracting the entire archive requires the specification of an output file to prevent accidental blasts of binary content to the console.)

humility flash

Flashes the target with the image that is contained within the specified archive (or dump). As a precautionary measure, if the specified archive already appears to be on the target, humility flash will fail unless the-F (--force) flag is set. Because this will only check the image ID (and not the entire image), humility flash can be optionally told to verify that all of the program text in the image is on the device by specifying -V (--verify). Similarly, if one wishes to _only_check the image against the archive (and not flash at all), specify-C (--check).

This attempts to natively flash the part within Humility using probe-rs, but for some parts or configurations, it may need to use OpenOCD as a child process to flash it. If OpenOCD is required but not installed (or isn't in the path), this will fail. If OpenOCD is used, temporary files are created as part of this process; if they are to be retained, the -R(--retain-temporaries) flag should be set. To see what would be executed without actually executing any commands, use the -n(--dry-run) flag. Should use of OpenOCD need to be forced (that is, should probe-rs flashing fail), the -O (--force-openocd) flag can be used. That said, OpenOCD should generally be discouraged; the disposition is to extend probe-rs to support any parts that must be flashed via OpenOCD.

If the specified archive includes auxiliary flash data and the new image includes a task with the AuxFlash API, two slots of auxiliary flash will be programmed after the image is written. See RFD 311 for more information about auxiliary flash management.

humility gdb

This command launches GDB and attaches to a running device.

By default, the user must be running openocd or pyocd in a separate terminal.

The --run-openocd option automatically launches openocd based on theopenocd.cfg file included in the build archive.

When using pyocd, it must be launched with the --persist option, because humility gdb connects to it multiple times (once to check the app id, then again to run the console).

humility gimlet

humility gimlet contacts a (recent firmware version) Gimlet over the management network and extracts certain live diagnostic information.

$ humility gimlet --ip fe80::0c1d:9aff:fe64:b8c2%en0 read-seq-regs

For a complete list of subcommands, use humility gimlet --help.

humility gpio

humility gpio allows for GPIO pins to be set, reset, queried or configured on STM32 targets. Commands:

Set, reset, toggle

To change the state of a pin (or pins), specify the pin (or pins) and the desired command. For example, to toggle the state on pin 14 on port B:

$ humility gpio --toggle --pins B:14 humility: attached via ST-Link V3 [Ok([])]

To set pins B:0, B:14 and E:1:

$ humility gpio --set --pins B:0,B:14,E:1 humility: attached via ST-Link V3 [Ok([]), Ok([]), Ok([])]

To reset pin E:1:

$ humility gpio --reset --pins E:1 humility: attached via ST-Link V3 [Ok([])]

Input

To get input values for a particular pin:

$ humility gpio --input --pins B:0,B:14,E:1 humility: attached via ST-Link V3 B:0 = 1 B:14 = 1 E:1 = 0

To get input values for all pins, leave the pin unspecified:

Port A 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1 1 Port B 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 Port C 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Port D 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 Port E 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Port F 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Port G 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Port H 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Port I 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Port J 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Port K 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Configure

To configure a pin, the configuration should be specified as a colon-delimited 5-tuple consisting of:

For example, to configure pin 5 on port A as a push-pull output:

$ humility gpio -c Output:PushPull:High:None:AF0 -p A:5

humility hash

Uses the hash task to hash sequences. The following are all equivalent:

$ humility hash --digest -s abc $ humility hash --digest -x 61,62,63 $ echo -n abc > abc.txt ; humility hash --digest -f abc.txt $ hash -i --update -s 'a' ; hash --update -s 'bc' ; hash --finalize

Note that --update can also take a filename as a parameter.

humility hiffy

humility hiffy allows for querying and manipulation of hiffy, the HIF agent present in Hubris. To list all Idol interfaces present in Hubris, use the -l (--list) option, optionally specifying a filter for tasks or interface names if so desired:

$ humility hiffy -l user_leds humility: attached via ST-Link INTERFACE TASK UserLeds user_leds | +--> UserLeds.led_on | index usize | () | LedError | +--> UserLeds.led_off | index usize | () | LedError | +--> UserLeds.led_toggle index usize () LedError

To enlist the Hubris agent to call a particular interface and operation, use -c (--call), using -a (--arguments) to indicate any arguments, e.g.:

$ humility hiffy -c UserLeds.led_toggle -a index=0 humility: attached via ST-Link UserLeds.led_toggle() = ()

To view the raw HIF functions provided to programmatic HIF consumers within Humility, use -L (--list-functions).

humility host

humility host pretty-prints host state, which is sent to the SP over IPCC.

It is only functional on a Gimlet SP image.

humility host last-panic

Pretty prints the value of LAST_HOST_PANIC

% humility: attached to dump version: 2 (inferred) cause: IPCC_PANIC_TRAP error: 0 cpuid: 0 thread: 0xfffff78809c74c20 time: 74.639002555 (1970-01-01T00:01:14.639002555+00:00) hrtime: 74639011110 addr: 0xfffffcf853a0f940 pc: 0xfffffffffbc5fb45 fp: 0xfffff78809c748f0 rp: 0xfffff78809c749e0 registers: rdi 0xfffffffffc029d70 rsi 0xfffff78809c749d8 rdx 0xfffffffffc029d70 rcx 0x0 r8 0xfffffcf931453280 r9 0x6 rax 0x0 rbx 0xfffffcf931453280 rbp 0xfffff78809c74b60 r10 0x1 r11 0xfffffffff7c9c510 r12 0xfffffcf931da7210 r13 0xfffffcf931453370 r14 0x0 fsb 0xfffffffffc2604e8 gsb 0xfffff78809c74a90 es 0x0 fs 0x0 gs 0x0 tra 0x6 err 0x0 rip 0xfffffffffc029d70 cs 0x30 rfl 0x10246 rsp 0xfffff78809c74ad8 ss 0x38 message: BAD TRAP: type=6 (#ud Invalid opcode) rp=fffff78809c749e0 addr=fffffcf853a0f940 stack: die+0x105 (0xfffffffffbc5fb45) trap+0x855 (0xfffffffffbc606f5) cmntrap+0xe9 (0xfffffffffbc49819) clock+0x0 (0xfffffffffc029d70) cbe_softclock+0x23 (0xfffffffffbc0c8b3) av_dispatch_softvect+0x72 (0xfffffffffbccbf02) apix_dispatch_softint+0x35 (0xfffffffff7c9c545) switch_sp_and_call+0x15 (0xfffffffffbc834b5) apix_do_softint+0x5a (0xfffffffff7c9c5ba) apix_do_interrupt+0x2bf (0xfffffffff7c9d06f) cmnint+0xc3 (0xfffffffffbc00233) taskq_bucket_extend+0x15b (0xfffffffffc17a66b) taskq_create_common+0x33a (0xfffffffffc17a19a) system_taskq_init+0x4e (0xfffffffffc1788de) main+0xbb (0xfffffffffc0c50bb) _locore_start+0x88 (0xfffffffffbc49708)

humility host boot-fail

Pretty-prints the contents of LAST_HOST_BOOT_FAIL

$ humility host boot-fail humility: attached to dump humility: reading LAST_HOST_BOOT_FAIL [0; 4096]

humility hydrate

humility hydrate combines a raw memory dump (obtained from MGS) and a Hubris archive, forming a proper Hubris dump.

$ humility -a build-grapefruit-image-default.zip hydrate hubris.dry.0

The archive is required, because the raw memory dump does not contain debug information.

By default, this writes to hubris.core.TASK_NAME.N (where N is the lowest available value); use --out to specify a different path name.

humility i2c

On platforms that have I2C support, humility i2c can be used to scan a bus, scan a device, read a register, or write a register. Its usage will be specific to the board being examined; to specify a controller use the -c, to specify a port (if necessary), use -p; to specify a mux and segment (if necessary), use -m.

For example, on a Gimletlet, here is a scan of controller I2C3, revealing one device at address 0x48:

$ humility i2c -s -c 3 humility: attached via ST-Link

Device scan on controller I2C3:

R = Reserved   - = No device   \o/ = Device found   X = Timed out

ADDR 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf 0x00 R R R R R R R R - - - - - - - - 0x10 - - - - - - - - - - - - - - - - 0x20 - - - - - - - - - - - - - - - - 0x30 - - - - - - - - - - - - - - - - 0x40 - - - - - - - - \o/ - - - - - - - 0x50 - - - - - - - - - - - - - - - - 0x60 - - - - - - - - - - - - - - - - 0x70 - - - - - - - - - - - - R R R R

To scan that device, specify its address via -d:

$ humility i2c -s -c 3 -d 0x48 humility: attached via ST-Link

Register scan for device 0x48 on I2C3:

  - = No register        ! = No device        X = Timed out

ADDR 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf 0x00 0b c8 80 00 20 00 05 00 49 80 05 cb 00 00 00 00 0x10 00 00 00 00 00 00 00 00 6c 00 06 00 00 00 00 00 0x20 0b c8 80 00 20 00 05 00 49 80 05 cb 00 00 00 00 0x30 00 00 00 00 00 00 00 00 6c 00 06 00 00 00 00 00 0x40 00 00 80 00 20 00 05 00 49 80 05 cb 00 00 00 00 0x50 00 00 00 00 00 00 00 00 6c 00 06 00 00 00 00 00 0x60 00 00 80 00 20 00 05 00 49 80 05 cb 00 00 00 00 0x70 00 00 00 00 00 00 00 00 6c 00 06 00 00 00 00 00 0x80 00 00 80 00 20 00 05 00 49 80 05 cb 00 00 00 00 0x90 00 00 00 00 00 00 00 00 6c 00 06 00 00 00 00 00 0xa0 00 00 80 00 20 00 05 00 49 80 05 cb 00 00 00 00 0xb0 00 00 00 00 00 00 00 00 6c 00 06 00 00 00 00 00 0xc0 00 00 80 00 20 00 05 00 49 80 05 cb 00 00 00 00 0xd0 00 00 00 00 00 00 00 00 6c 00 06 00 00 00 00 00 0xe0 00 00 80 00 20 00 05 00 49 80 05 cb 00 00 00 00 0xf0 00 00 00 00 00 00 00 00 6c 00 06 00 00 00 00 00

(This device is an ADT7420 temp sensor.) To look at a particular register, elide -s and specify the register of interest via -r:

$ humility i2c -c 3 -d 0x48 -r 0xb humility: attached via ST-Link Controller I2C3, device 0x48, register 0xb = 0xcb

To write a value to a register, specify the -w flag, along with the value to write, e.g. (for the ADT7420), the MSB of the THIGHregister:

$ humility i2c -c 3 -d 0x48 -r 0x4 -w 0x1f humility: attached via ST-Link Controller I2C3, device 0x48, register 0x4 = 0x1f

Note that if registers are not writable, the write will (generally) be silently discarded by the device; it can be useful to read the register after writing it to confirm that the value is as expected:

$ humility i2c -c 3 -d 0x48 -r 0x4 humility: attached via ST-Link Controller I2C3, device 0x48, register 0x4 = 0x1f

To determine the last mux and segment to be enabled on a particular controller/port, use --lastmux (-l):

$ humility i2c -b front --lastmux humility: attached via ST-Link V3 last selected mux/segment for I2C2, port F: mux 3, segment 2

humility ibc

Interface to BMR491 power regulator

This regulator is present on Gimlet and Sidecar PCAs. Right now,humility ibc only exposes one subcommand: black-box.

humility ibc black-box allows you to read out the blackbox log from the power converter. This can be used to debug previous faults. The log is stored in non-volatile memory, so it should be persistent through power loss.

Here's an example:

$ humility ibc black-box humility: attached to 0483:374e:001B00083156501320323443 via ST-Link V3 FAULT EVENT EVENT_INDEX: 0 TIMESTAMP 0x000a3747 = 18 hr, 35 min, 51.1 sec EVENT_ID 0x0000 STATUS_WORD 0x0010 0x0010: Output overcurrent fault STATUS_IOUT 0x80 0x80: Iout Overcurrent Fault STATUS_MFR 0x00 V_IN 0xf84f = 39.500V V_OUT 0x6000 = 12.000V I_OUT 0x0075 = 117.000A TEMPERATURE 0x0023 = 35.000°C FAULT EVENT EVENT_INDEX: 1 TIMESTAMP 0x000a3751 = 18 hr, 35 min, 52.1 sec EVENT_ID 0x0001 STATUS_WORD 0x0001 0x0001: System event STATUS_MFR 0x01 0x01: INPUT_LOW_EVENT V_IN 0xf83c = 30.000V V_OUT 0x0000 = 0.000V I_OUT 0x0000 = 0.000A TEMPERATURE 0x0000 = 0.000°C FAULT EVENT EVENT_INDEX: 2 TIMESTAMP 0x2809e751 = 777 day, 11 hr, 22 min, 48.1 sec EVENT_ID 0x0002 STATUS_WORD 0x0001 0x0001: System event STATUS_MFR 0x02 0x02: CANCEL_EVENT V_IN 0xf86b = 53.500V V_OUT 0x5f00 = 11.875V I_OUT 0x0000 = 0.000A TEMPERATURE 0x0012 = 18.000°C FAULT EVENT EVENT_INDEX: 3 TIMESTAMP 0x50099751 = 1554 day, 4 hr, 9 min, 44.1 sec EVENT_ID 0x0003 STATUS_WORD 0x0001 0x0001: System event STATUS_MFR 0x02 0x02: CANCEL_EVENT V_IN 0xf86b = 53.500V V_OUT 0x6000 = 12.000V I_OUT 0x0000 = 0.000A TEMPERATURE 0x0020 = 32.000°C LIFECYCLE EVENT EVENT_INDEX: 24 TIMESTAMP 0xffef8ad0 = 4969 day, 18 hr, 41 min, 12.0 sec EVENT_ID 0x0680 STATUS_WORD 0x0001 0x0001: System event STATUS_MFR 0x04 0x04: CLR_EVENT V_IN 0xf86b = 53.500V V_OUT 0x5f00 = 11.875V I_OUT 0x0000 = 0.000A TEMPERATURE 0x001a = 26.000°C LIFECYCLE EVENT EVENT_INDEX: 25 TIMESTAMP 0xffef8bd4 = 4969 day, 18 hr, 41 min, 38.0 sec EVENT_ID 0x0681 STATUS_WORD 0x0001 0x0001: System event STATUS_MFR 0x05 0x05: ERASE_OVFL_EVENT V_IN 0xf860 = 48.000V V_OUT 0x5f00 = 11.875V I_OUT 0x0000 = 0.000A TEMPERATURE 0x001b = 27.000°C

The log doesn't appear to be completely reliable, especially with respect to timestamps, so take it with a grain of salt and with the datasheet close at hand. For example, the machine in the example above had not be up for 777 days (or, for that matter, for 4,969).

humility jefe

Humility allows for some (well-defined) manipulation of tasks via jefe, the Hubris supervisor. By default, jefe will carry out a configured set of responses if tasks fault -- restarting them unless configured otherwise. The policy that governs Jefe's response to task failure is called the_disposition._ While debugging, it can be useful to change Jefe's disposition on a particular task, so that the task will not automatically restart on fault. This is done with the -H/--hold option:

$ humility jefe --hold ping humility: attached via ST-Link humility: successfully changed disposition for ping

This doesn't make any immediate changes to the task, but merely updates a table inside jefe. When the task next faults, it will not be restarted, e.g.:

$ humility tasks ping humility: attached via ST-Link system time = 26597 ID TASK GEN PRI STATE 8 ping 121 4 FAULT: divide by zero (was: ready)

This can be particularly useful to couple with either humility dump orhumility tasks -sl:

$ humility tasks -sl ping humility: attached via ST-Link system time = 103879 ID TASK GEN PRI STATE 8 ping 121 4 FAULT: divide by zero (was: ready) | +---> 0x200065b0 0x0802a05e task_ping::divzero @ /home/bmc/hubris/task/ping/src/main.rs:24 0x20006600 0x0802a0fe userlib::sys_panic @ /home/bmc/hubris/sys/userlib/src/lib.rs:678 0x20006600 0x0802a0fe main @ /home/bmc/hubris/task/ping/src/main.rs:35

To change the disposition of a task (back) to be restarted, use the--release/-r flag:

$ humility jefe --release ping humility: attached via ST-Link humility: successfully changed disposition for ping

--release undoes the effect of --hold. If the task is parked at a fault, it will be restarted immediately. Otherwise just the disposition will be updated and the task will be left alone.

If you would like to cause a task to restart, use the --start/-s flag. This will restart a running task immediately, and will re-run a held task_without releasing the hold._ This means the task will still be caught at the next fault, giving you a way of precisely trying an operation again.

To inject a fault into a task, use the --fault/-f flag. This will causejefe to use Kernel Trickery(tm) to inject a fault into the target task, and also switch its disposition to "held" so you can inspect the result. The injected fault has a dedicated type to make clear that the fault originated outside of the task:

$ humility jefe --fault pong humility: attached via ST-Link humility: successfully changed disposition for pong $ humility tasks pong humility: attached via ST-Link system time = 191227 ID TASK GEN PRI STATE 7 pong 0 3 FAULT: killed by jefe/gen0 (was: recv, notif: bit0) | +---> 0x200063b8 0x08028c0a userlib::sys_recv_stub @ /home/bmc/hubris/sys/userlib/src/lib.rs:288 0x20006400 0x080280ac userlib::sys_recv @ /home/bmc/hubris/sys/userlib/src/lib.rs:236 0x20006400 0x080280ba main @ /home/bmc/hubris/task/pong/src/main.rs:13

As with tasks held by --hold, use --release/-r to set the task back to normal, or --start/-s to run it once but catch the next fault.

humility lpc55gpio

The LPC55-equivalent of humility gpio, allowing for GPIO pins to be set, reset, queried or configured on LPC55 targets. Commands:

Set, reset, toggle

To change the state of a pin (or pins), specify the pin (or pins) and the desired command. For example, to toggle the state on pin PIO0_17:

$ humility lpc55gpio --toggle --pins PIO0_17 humility: attached via CMSIS-DAP [Ok([])]

To set pins PIO0_15, PIO0_16 and PIO0_17:

$ humility lpc55gpio --set --pins PIO0_15,PIO0_16,PIO0_17 humility: attached via CMSIS-DAP [Ok([]), Ok([]), Ok([])]

To reset pin PIO0_17:

$ humility lpc55gpio --reset --pins PIO0_17 humility: attached via CMSIS-DAP [Ok([])]

Input

To get input values for a particular pin:

$ humility lpc55gpio --input --pins PIO0_10,PIO0_11,PIO1_0 humility: attached via CMSIS-DAP PIO0_10 = 0 PIO0_11 = 1 PIO1_0 = 0

To get input values for all pins, leave the pin unspecified:

$ humility lpc55gpio --input humility: attached via ST-Link V3 humility: attached to 1fc9:0143:12UNOSLDXOK51 via CMSIS-DAP PIO0_0 = 0 PIO0_1 = 0 PIO0_2 = 0 PIO0_3 = 0 PIO0_4 = 0 PIO0_5 = 1 PIO0_6 = 0 PIO0_7 = 0 PIO0_8 = 0 PIO0_9 = 1 PIO0_10 = 0 PIO0_11 = 1 PIO0_13 = 0 ...

Configure, direction

To configure a pin, the configuration should be specified as a colon-delimited 6-tuple consisting of:

Note that the direction of the pin should also likely be configured; this is done via the --direction option, specifying either Input orOutput. For example, to configure pin PIO0_17 to be an output:

$ humility lpc55gpio -c Alt0:NoPull:Standard:Disable:Digital:Normal -p PIO0_17 humility: attached via CMSIS-DAP [Ok([])] $ humility lpc55gpio -p PIO0_17 --direction Output humility: attached via CMSIS-DAP [Ok([])]

humility lsusb

humility lsusb will show you Humility's view of the USB devices available on the system, to help you choose probes and/or diagnose permissions issues.

humility manifest

humility manifest displays information about the Hubris archive. It does not connect at all to a Hubris target to operate. In addition to archive-wide attributes, humility manifest displays the features enabled for each task, as well as any device toplogy information present in the archive, e.g.:

$ humility manifest version => hubris build archive v1.0.0 git rev => 753a57169eba699e73ee59e0cf5345eb1d6e1ae2-dirty board => nucleo-h743zi2 name => demo-stm32h753-nucleo target => thumbv7em-none-eabihf features => h743, itm total size => 140K kernel size => 30K tasks => 12 ID TASK SIZE FEATURES 0 hiffy 42.9K h743, stm32h7, itm, i2c, gpio, qspi 1 jefe 6.7K itm 2 i2c_driver 9.8K h743 3 spi_driver 10.7K spi3, h743 4 hf 8.6K h743 5 rcc_driver 4.7K h743 6 gpio_driver 5.8K h743 7 usart_driver 5.9K h743 8 user_leds 5.5K stm32h7 9 pong 4.7K 10 ping 5.2K uart 11 idle 0.1K i2c buses => 1 controller, 1 bus C PORT MODE NAME DESCRIPTION 2 F init - -

humility manifest can operate on either an archive or on a dump.

humility map

One common pathology in Hubris tasks is a fault induced when a task attempts to access a memory address outside of its designated regions. (This can happen, for example, because the task attempted to access device memory that was not allocated to it in the build description, because it exceeded the device memory allocated to it, or because it allocated the memory allocated to it, e.g., because of a stack overflow.) humility tasks can be useful to see this happening; a non-zero generation count will indicate that a task has been restarted -- and the log message fromjefe will indicate the specific address, e.g.:

$ humility itm -ea humility: attached via OpenOCD humility: core halted humility: core resumed humility: TPIU sync packet found at offset 1 humility: ITM synchronization packet found at offset 12 Task #7 Memory fault at address 0x200028fc Task #7 Memory fault at address 0x200028fc ^C

To better understand the memory that a task is trying to access, one can run the humility map command, which shows the memory regions that have been mapped into tasks, in address order:

$ humility -a ~/hubris/target/demo/dist/build-demo.zip map humility: attached via OpenOCD DESC LOW HIGH SIZE ATTR ID TASK 0x08004864 0x08010000 - 0x08017fff 32KiB r-x--- 0 jefe 0x08004884 0x08018000 - 0x08019fff 8KiB r-x--- 1 rcc_driver 0x080048a4 0x0801c000 - 0x0801ffff 16KiB r-x--- 2 usart_driver 0x080048c4 0x08020000 - 0x08023fff 16KiB r-x--- 3 user_leds 0x080048e4 0x08024000 - 0x08025fff 8KiB r-x--- 4 ping 0x08004904 0x08026000 - 0x08027fff 8KiB r-x--- 5 pong 0x08004924 0x08028000 - 0x080280ff 256 r-x--- 6 idle 0x08004944 0x0802a000 - 0x0802bfff 8KiB r-x--- 7 oh_no 0x08004964 0x0802c000 - 0x0802dfff 8KiB r-x--- 8 oh_no2 0x08004874 0x20001000 - 0x200013ff 1KiB rwx--- 0 jefe 0x08004894 0x20001400 - 0x200017ff 1KiB rwx--- 1 rcc_driver 0x080048b4 0x20001800 - 0x20001bff 1KiB rwx--- 2 usart_driver 0x080048d4 0x20001c00 - 0x20001fff 1KiB rwx--- 3 user_leds 0x080048f4 0x20002000 - 0x200021ff 512 rwx--- 4 ping 0x08004914 0x20002400 - 0x200027ff 1KiB rwx--- 5 pong 0x08004934 0x20002800 - 0x200028ff 256 rwx--- 6 idle 0x08004954 0x20002900 - 0x200029ff 256 rwx--- 7 oh_no 0x08004974 0x20002a00 - 0x20002aff 256 rwx--- 8 oh_no2 0x08004824 0x40004400 - 0x400047ff 1KiB rw-d-- 2 usart_driver 0x08004844 0x40020000 - 0x400203ff 1KiB rw-d-- 2 usart_driver 0x08004854 0x40020c00 - 0x40020fff 1KiB rw-d-- 3 user_leds 0x08004834 0x40023800 - 0x40023bff 1KiB rw-d-- 1 rcc_driver

(In this case, task 7, oh_no, has overflowed its stack -- which we can see from the map output has been sized to only 256 bytes.)

humility monorail

humility monorail exposes commands to interact with the management network switch and PHYs. It is for management of the management network, and can therefore only be run on two images:

Use humility monorail -h to see help, or humility monorail status for a bird's-eye view of the ports.

humility monorail read

The read subcommand allows you to read a register from the VSC7448 switch IC. Registers can be specified in a few ways, but most of the time, you'll want to execute a read by register name:

$ export HUMILITY_TARGET=sidecar $ humility monorail read DEV1G[0]:DEV_RST_CTRL humility: attached to 0483:374f:002A001C4D46500F20373033 via ST-Link V3 humility: Reading DEV1G[0]:DEV_CFG_STATUS:DEV_RST_CTRL from 0x71040000 DEV1G[0]:DEV_CFG_STATUS:DEV_RST_CTRL => 0x100000 bits | value | field 21:20 | 0x1 | SPEED_SEL 12 | 0x0 | PCS_TX_RST 8 | 0x0 | PCS_RX_RST 4 | 0x0 | MAC_TX_RST 0 | 0x0 | MAC_RX_RST

It's not necessary to use the fully qualified TARGET:GROUP:REGISTER form; any unambiguous subset will work (e.g. in the example above, we usedDEV1G[0]:DEV_RST_CTRL instead of the fullDEV1G[0]:DEV_CFG_STATUS:DEV_RST_CTRL). If your register name is not unambiguous, an error will be printed.

Register names can be found in thevsc7448-pac crate, which is automatically generated from Microchip's C SDK header files.

It's also possible to execute reads by raw address:

$ humility monorail read 0x71040000 humility: attached to 0483:374f:002A001C4D46500F20373033 via ST-Link V3 humility: Reading DEV1G[0]:DEV_CFG_STATUS:DEV_RST_CTRL from 0x71040000 DEV1G[0]:DEV_CFG_STATUS:DEV_RST_CTRL => 0x100000 bits | value | field 21:20 | 0x1 | SPEED_SEL 12 | 0x0 | PCS_TX_RST 8 | 0x0 | PCS_RX_RST 4 | 0x0 | MAC_TX_RST 0 | 0x0 | MAC_RX_RST

humility monorail write

Modifies a register in the VSC7448 switch. Note that there is no checking of read/write vs read-only registers; good luck!

humility monorail info

The info subcommand looks up info on a register in the VSC7448 switch IC. This command is offline, meaning it does not require an attached system.

$ humility monorail info HW_QSGMII_CFG Register HSIO:HW_CFGSTAT:HW_QSGMII_CFG Register address: 0x71460170 bits | field 13 | E_DET_ENA 11:0 | FLIP_LANES 14 | SHYST_DIS 12 | USE_I1_ENA

If you provide a value as the final argument, it will decode the register and pretty-print a table:

$ humility monorail info HW_QSGMII_CFG 0x2000 Register HSIO:HW_CFGSTAT:HW_QSGMII_CFG Register address: 0x71460170 Register value: 0x2000 bits | value | field 14 | 0x0 | SHYST_DIS 13 | 0x1 | E_DET_ENA 12 | 0x0 | USE_I1_ENA 11:0 | 0x0 | FLIP_LANES

humility monorail status

Prints a table showing the status of every port in the system, along with their PHY (if present). The -p argument allows you to specify a subset of ports, e.g.

$ humility monorail status -p40,41,42,43,44,45 humility: attached to 0483:374f:002A001C4D46500F20373033 via ST-Link V3

PORT MODE SPEED DEV SERDES LINK PHY MAC LINK MEDIA LINK
40 QSGMII 100M 1G_16 6G_14 up VSC8504 down down
41 QSGMII 100M 1G_17 6G_14 up VSC8504 down up
42 QSGMII 100M 1G_18 6G_14 up VSC8504 down down
43 QSGMII 100M 1G_19 6G_14 up VSC8504 down down
44 QSGMII 1G 1G_20 6G_15 up VSC8562 up up
45 QSGMII 1G 1G_21 6G_15 up VSC8562 up up
humility monorail dump

Dumps an entire top-level target on the VSC7448, e.g. DEV1G[0]

$ humility monorail dump DEV1G[0] humility: attached to 0483:374f:002A001C4D46500F20373033 via ST-Link V3 Dumping target DEV1G[0] (0x71040000 -> 0x710400a0) DEV1G[0]:DEV_CFG_STATUS:DEV_RST_CTRL 0x00100000 DEV1G[0]:DEV_CFG_STATUS:DEV_STICKY 0x00004000 DEV1G[0]:DEV_CFG_STATUS:DEV_DBG_CFG 0x00000800 DEV1G[0]:DEV_CFG_STATUS:DEV_PORT_PROTECT 0x00000000 DEV1G[0]:DEV_CFG_STATUS:EEE_CFG 0x0011940a DEV1G[0]:DEV_CFG_STATUS:PTP_CFG 0x00400000 DEV1G[0]:DEV_CFG_STATUS:PTP_EVENTS 0x00000000 ...

This subcommand is rather fragile; large targets may overflow the HIF return stack, and it's possible to access invalid registers.

humility monorail mac

Prints the MAC table of the VSC7448 switch. This table shows which MAC addresses have be learned on each port.

$ humility monorail mac humility: attached to 0483:374f:002A001C4D46500F20373033 via ST-Link V3 Reading 3 MAC addresses...

PORT MAC
18 0e:1d:23:88:1a:3b
41 0e:1d:7f:c3:07:31
48 0e:1d:15:70:3d:bb
humility monorail counters

Prints or resets (with -r) counters for a port on the VSC7448.

$ humility monorail counters -p48 humility: attached to 0483:374f:002A001C4D46500F20373033 via ST-Link V3 Packet counters: (port 48) Receive: Unicast: 0 Multicast: 1049 Broadcast: 0 Transmit: Unicast: 0 Multicast: 2099 Broadcast: 0

humility monorail phy

Subcommand to interact with PHYs on a per-port basis. Supports read,write, info, and dump sub-subcommands, which behave similarly to the commands to interact with VSC7448 registers.

PHY register names are also found in thevsc7448-pac crate.

humility mwocp

humility mwocp allows for flashing the MWOCP68 family of PSUs with a firmware payload specified via the --flash option.

Like humility pmbus, a device can be specified via an address (along with an I2C bus or controller and port) or via a PMBus rail. Note that either the 54V or 12V rail can be used; it is only used to identify the PSU.

$ humility mwocp -r V54_PSU1 -f ./FW_M5813_F1_v0_7_62.bin humility: starting update; revision is currently 0701-0701-0000 humility: writing boot loader key humility: sleeping for 3 seconds... ... humility: flashed 32.00KB in 2 minutes humility: sending checksum (0x0036f1c7) humility: sleeping for 2 seconds... humility: checksum successful! humility: resetting PSU humility: sleeping for 5 seconds... humility: update complete; revision is now 0762-0701-0000

Note that the MWOCP68 itself may reject firmware that is self-consistent (i.e., valid checksum) but invalid; in this case, an error won't be indicated, but the revision will not change across the update.

humility net

humility net exposes commands to interact with the management network from the client's perspective.

(It is the counterpart to humility monorail, which interacts with the management network from the switch's perspective.)

It is fully functional on

These PCAs have the KSZ8463 switch + VSC85x2 PHY which is our standard management network interface.

humility net ip

The ip subcommand works on any image with network functionality, and prints the MAC and IPv6 address of the board. Note that on boards with multiple ports, this is the lowest MAC / IPv6 address.

humility net mac

This subcommand prints the MAC table from the KSZ8463 switch. It is functional on the boards listed above and the Gimletlet (when the NIC daughterboard is installed)

humility net status

This subcommand shows the status of the management network links. It is only functional on the fully supported boards listed above.

humility net counters

This subcommand shows the internal counters on the management network links. It is only functional on the fully supported boards listed above. In addition, the MAC-side counters are only supported on the VSC8562, not the VSC8552; this is indicated with -- in the relevant table positions.

humility openocd

This command launches OpenOCD based on the config file in a build archive, which then allows one to connect with either GDB or directly via telnet. If the intention is to only run GDB, note that humility gdb --run-openocdwill both run OpenOCD and run a foreground GDB that is connected to it.

humility pmbus

Operates on PMBus devices in the system. To list all PMBus devices, use--list (-l):

$ humility pmbus --list C P MUX ADDR DEVICE RAILS 3 H - 0x24 tps546b24a V3P3_SP_A2 3 H - 0x26 tps546b24a V3P3_SYS_A0 3 H - 0x27 tps546b24a V5_SYS_A2 3 H - 0x29 tps546b24a V1P8_SYS_A2 3 H - 0x5a raa229618 VDD_VCORE, VDD_MEM_ABCD 3 H - 0x5b raa229618 VDDCR_SOC, VDD_MEM_EFGH 3 H - 0x5c isl68224 VPP_ABCD, VPP_EFGH, V1P8_SP3 4 F - 0x10 adm1272 V54_FAN 4 F - 0x14 adm1272 V54_HS_OUTPUT 4 F - 0x25 tps546b24a V0P96_NIC_VDD_A0HP 4 F - 0x67 bmr491 V12_SYS_A2

To query a particular device, specify the device by its I2C identity (controller/port, segment, address):

$ humility pmbus -d 0x67 -c 4 -p f 0x01 OPERATION 0x84 0x02 ON_OFF_CONFIG 0x18 0x10 WRITE_PROTECT 0x00 0x19 CAPABILITY 0xb0 0x20 VOUT_MODE 0x15 0x21 VOUT_COMMAND 0x6000 = 12.000V 0x22 VOUT_TRIM 0x0000 = 0.000V 0x23 VOUT_CAL_OFFSET 0xffb4 = 31.963V 0x24 VOUT_MAX 0x7333 = 14.400V 0x25 VOUT_MARGIN_HIGH 0x699a = 13.200V 0x26 VOUT_MARGIN_LOW 0x5666 = 10.800V 0x27 VOUT_TRANSITION_RATE 0x9b02 = 0.094V/ms 0x28 VOUT_DROOP 0xe800 = 0.000mV/A ...

In the unusual case that a device is unknown to the system (that is, it does not appear in humility manifest), you can force a particular PMBus driver by using --driver (-D).

For the common case of devices known to the system, you can specify a device by name if it matches a single device in the system (e.g., humility pmbus -d bmr491). In lieu of specifying a device, you can specify a rail via--rail (-r), e.g.:

$ humility pmbus --rail VDD_MEM_EFGH humility: attached via ST-Link V3 0x00 PAGE 0x01 = 1 0x01 OPERATION 0x48 0x02 ON_OFF_CONFIG 0x16 0x04 PHASE 0x00 = 0 0x07 ZONE_CONFIG 0xfefe 0x08 ZONE_ACTIVE 0x0000 0x10 WRITE_PROTECT 0x00 0x19 CAPABILITY 0xd4 0x20 VOUT_MODE 0x40 0x21 VOUT_COMMAND 0x04ce = 1.230V 0x22 VOUT_TRIM 0x0000 = 0.000V 0x23 VOUT_CAL_OFFSET 0x0000 = 0.000V 0x24 VOUT_MAX 0x05dc = 1.500V 0x25 VOUT_MARGIN_HIGH 0x03b1 = 0.945V 0x26 VOUT_MARGIN_LOW 0x0357 = 0.855V 0x27 VOUT_TRANSITION_RATE 0x09c4 = 0.025V/μs 0x28 VOUT_DROOP 0x0014 = 0.200mV/A ...

You can specify a command (or commands) to run with --command (-C); this can be useful when paired with the --verbose (-v) flag to deconstruct a particular command result:

$ humility pmbus -r VDD_MEM_ABCD --command STATUS_WORD --verbose humility: attached via ST-Link V3 0x79 STATUS_WORD 0x0000 | | b15 0b0 = no fault <= OutputVoltageFault | b14 0b0 = no fault <= OutputCurrentFault | b13 0b0 = no fault <= InputFault | b12 0b0 = no fault <= ManufacturerFault | b11 0b0 = POWER_GOOD set <= PowerGoodStatus | b10 0b0 = no fault <= FanFault | b9 0b0 = no fault <= OtherFault | b8 0b0 = no fault <= UnknownFault | b7 0b0 = no fault <= Busy | b6 0b0 = power is not off <= Off | b5 0b0 = no fault <= OutputOvervoltageFault | b4 0b0 = no fault <= OutputOvercurrentFault | b3 0b0 = no fault <= InputUndervoltageFault | b2 0b0 = no fault <= TemperatureFault | b1 0b0 = no fault <= CMLFault | b0 0b0 = no fault <= NoneOfTheAbove +-----------------------------------------------------------------------

You can also write a PMBus command with --write (-w), which allows for for particular fields to be written, e.g.:

$ humility pmbus -r VDD_VCORE -w OPERATION.MarginFaultResponse=ActUpon humility: attached via ST-Link V3 humility: I2C3, port H, dev 0x5a, rail 0: successfully wrote OPERATION

It should go without saying that this should be done carefully!

To get specific help on what fields may be written and the legal values for those fields, use --commandhelp (-H):

$ humility pmbus -r VDD_VCORE --commandhelp OPERATION 0x01 OPERATION | b7 OnOffState <= On/off state | 0b0 = Off <- output off | 0b1 = On <- output on | b6 TurnOffBehavior <= Power down behavior | 0b0 = Clear <- powers down immediately | 0b1 = Set <- powers down based on TOFF_DELAY | b5:4 VoltageCommandSource <= Source of output voltage | 0b00 = VOUT_COMMAND <- set by VOUT_COMMAND | 0b01 = VOUT_MARGIN_LOW <- set by VOUT_MARGIN_LOW | 0b10 = VOUT_MARGIN_HIGH <- set by VOUT_MARGIN_HIGH | 0b11 = AVS_VOUT_COMMAND <- set by AVSBus | b3:2 MarginFaultResponse <= Margin fault response | 0b01 = Ignore <- ignore margin faults | 0b10 = ActUpon <- act upon margin faults | b1 TransitionControl <= Transition control | 0b0 = Clear <- not set | 0b1 = Set <- set +-----------------------------------------------------------------------

To get a summary of all PMBus rails in the system, use --summarize (-s):

$ humility pmbus --summarize humility: attached via ST-Link V3 DEVICE RAIL PG? #FLT VIN VOUT IOUT TEMP_1 tps546b24a V3P3_SP_A2 Y 0 11.969V 3.311V 0.404A 33.500°C tps546b24a V3P3_SYS_A0 Y 0 11.969V 3.309V 1.457A 36.250°C tps546b24a V5_SYS_A2 Y 0 11.969V 4.982V 0.518A 36.000°C tps546b24a V1P8_SYS_A2 Y 0 11.984V 1.797V 3.316A 34.750°C raa229618 VDD_VCORE Y 0 11.990V 1.181V 53.200A 40.000°C raa229618 VDD_MEM_ABCD Y 0 11.990V 1.224V 28.600A 41.000°C raa229618 VDDCR_SOC Y 0 11.950V 0.890V 18.200A 42.000°C raa229618 VDD_MEM_EFGH Y 0 11.950V 1.223V 27.400A 43.000°C isl68224 VPP_ABCD Y 0 11.950V 2.500V 0.400A 40.000°C isl68224 VPP_EFGH Y 0 11.950V 2.499V 0.500A 30.000°C isl68224 V1P8_SP3 Y 0 11.950V 1.796V 1.600A 0.000°C adm1272 V54_FAN Y 4 0x088c 0x088c 0x0810 30.452°C adm1272 V54_HS_OUTPUT Y 4 0x088c 0x088b 0x092e 30.690°C tps546b24a V0P96_NIC_VDD_A0HP Y 0 11.984V 0.955V 3.074A 37.500°C bmr491 V12_SYS_A2 Y 1 53.625V 11.995V 19.250A 35.750°C

Note that for some devices, it is not possible to get accurate voltage and current readings from pmbus alone, as knowledge of how the device is integrated into a larger system is required to interpret raw values. For these devices, the raw value is provided (as in the adm1272 output, above); to get the interpreted value, use humility power instead (which has the added advantage of displaying all power rails in the systemn, not just PMBus devices.)

humility pmbus can use two different mechanisms to perform PMBus actions, selected by the --agent command-line argument.

In practice, allowing humility pmbus to select the agent is almost always what you want.

humility power

humility power displays the values associated with power rails, displaying output voltage, output current, input voltate, input current, and temperature. Not all measurements are available for all rails; if a measurement is not provided for a given rail, "-" is printed. To specify which rails are displayed, use the --rails option. If a rail can provide a given measurement, but that measurement is unavailable (say, due to being in a power state whereby the rail is not powered), "x" is displayed. Some rails can determine current by output phase; to display these, use the --phase-current option.

humility powershelf

humility powershelf allows for remotely dumping the state of the PSC power shelves.

This command is currently hard-coded to support only the MWOCP68, and it dumps 50+ properties described in the ACAN-114 application note. It will only dump the properties from a single shelf+rail combination, so seeing properties of all 6 shelves requires calling this command 6 time (with indices 0 through 5).

humility probe

humility probe attempts to infer as much about the hardware state as it can, e.g.:

$ humility probe humility: attached via ST-Link humility: probe => STLink V3, VID 0483, PID 374e humility: probe serial => 003700303137511139383538 humility: core => Cortex-M7 humility: manufacturer => STMicroelectronics humility: chip => STM32H7, revision 0x2003 humility: status => executing humility: debug units => CSTF(x2) CTI(x2) DWT ETM FPB ITM SCS SWO TMC TPIU humility: CSTF => 0x5c004000, 0x5c013000 humility: CTI => 0x5c011000, 0xe0043000 humility: DWT => 0xe0001000 humility: ETM => 0xe0041000 humility: FPB => 0xe0002000 humility: ITM => 0xe0000000 humility: SCS => 0xe000e000 humility: SWO => 0x5c003000 humility: TMC => 0x5c014000 humility: TPIU => 0x5c015000 humility: ITM status => TRCENA enabled, TCR disabled, TER=0x0 humility: R0 => 0x20006000 humility: R1 => 0x20006000 humility: R2 => 0x0 humility: R3 => 0x0 humility: R4 => 0x0 humility: R5 => 0x0 humility: R6 => 0x0 humility: R7 => 0x0 humility: R8 => 0x0 humility: R9 => 0x0 humility: R10 => 0x0 humility: R11 => 0x0 humility: R12 => 0x0 humility: SP => 0x20006100 humility: LR => 0x802404f humility: PC => 0x8024052 humility: xPSR => 0x61000000 humility: MSP => 0x20000f48 humility: PSP => 0x20006100 humility: SPR => 0x7000000

If provided a Hubris archive, humility probe will display any register contents symbolically, e.g.:

$ humility -a ~/hubris/target/demo/dist/build-demo.zip probe humility: attached via ST-Link humility: probe => STLink V2-1, VID 0483, PID 374b humility: probe serial => 066DFF383032534E43132614 humility: core => Cortex-M4 humility: manufacturer => STMicroelectronics humility: chip => STM32F40x/STM32F41x, revision 0x1007 humility: debug units => DWT ETM FPB ITM SCS TPIU humility: status => executing humility: ITM => TRCENA enabled, TCR enabled, TER=0x3 humility: R0 => 0x0 humility: R1 => 0x0 humility: R2 => 0x1 humility: R3 => 0x20001bd4 humility: R4 => 0x20001bd4 humility: R5 => 0x801d988 humility: R6 => 0xb004 humility: R7 => 0x20001bf0 humility: R8 => 0x40004400 humility: R9 => 0x1 humility: R10 => 0x0 humility: R11 => 0xffff humility: R12 => 0x0 humility: SP => 0x20001ba8 humility: LR => 0x801c12b <- main+0xef humility: PC => 0x801d290 <- sys_recv_stub+0x1e humility: xPSR => 0x61000000 humility: MSP => 0x20000f48 humility: PSP => 0x20001ba8 humility: SPR => 0x7000000

humility qspi

humility qspi manipulates (and importantly, writes to) QSPI-attached flash in Hubris. To read the device identifier, use the --id (-i) option:

$ humility qspi -i humility: attached via ST-Link V3 DeviceIdData { manufacturer_id: Micron(0x20) memory_type: 3V(186) memory_capacity: 33554432 uid_n: 16 # If a Micron device: ext_device_id: 0b1000100 2nd device generation, Standard BP scheme, HOLD#/RESET#=HOLD Additional HW RESET# is available, Sector size is Uniform 64KB, device_configuration_info: 0 uid: [9a, ec, 0b, 00, 19, f9, ff$, 39, 00, be, 69, 97, f4, a2] } [Ok([20, ba, 19, 10, 44, 0, 9a, ec, b, 0, 19, f9, ff, 39, 0, be, 69, 97, f4, a2])]

To write an image from a file, use the --writefile (-W) option:

$ humility -W ./milan-spew-115k2-2dpc-0.4.1-dataeye.bin humility: attached via ST-Link V3 humility: erasing 16777216 bytes... humility: ... done humility: flashed 16.00MB in 5 minutes

If writing similar images, it is much faster to write only those blocks that differ. To perform a differential write, use the --diffwrite (-D) option:

$ humility qspi -D ./milan-spew-115k2-2dpc-0.4.1.bin humility: attached via ST-Link V3 humility: erasing 65536 bytes... humility: ... done humility: hashed 16.00MB, wrote 64.00KB in 16 seconds

To read, write or hash a particular region, use the --read (-r),--write (-w), or --hash (-H) respectively -- giving the address via --address (-a) and the number of bytes via --nbytes (-n). For example, to read 128 bytes from address 0x120000:

$ humility qspi -r -a 0x120000 -n 128 / 1 2 3 4 5 6 7 8 9 a b c d e f 0x00120000 | 24 50 53 50 ee 7a 31 28 10 00 00 00 20 cd 48 20 | $PSP.z1(.... .H 0x00120010 | 00 00 00 00 40 04 00 00 00 30 12 00 00 00 00 00 | ....@....0...... 0x00120020 | 01 00 00 00 00 54 01 00 00 40 12 00 00 00 00 00 | .....T...@...... 0x00120030 | 03 00 00 00 00 54 01 00 00 a0 13 00 00 00 00 00 | .....T.......... 0x00120040 | 08 00 00 00 40 ea 01 00 00 00 15 00 00 00 00 00 | ....@........... 0x00120050 | 09 00 00 00 40 06 00 00 00 f0 16 00 00 00 00 00 | ....@........... 0x00120060 | 0a 00 00 00 40 06 00 00 00 00 17 00 00 00 00 00 | ....@........... 0x00120070 | 0b 00 00 00 ff ff ff ff 01 00 00 00 00 00 00 00 | ................

To get the SHA256 hash for that same region:

$ humility qspi -H -a 0x120000 -n 128 humility: attached via ST-Link V3 120000..000080: 4d07112733efe240f990fad785726c52de4335d6c5c30a33e60096d4c2576742

By default, Hubris reserved sector 0 (the lowest 64 KiB) of QSPI for its own internal bookkeeping. To override this, use the --write-sector0 flag; this is required for erases and writes that would otherwise modify sector 0, as well as bulk erase.

humility readmem

humility readmem allows one to read a specified range of memory:

$ humility readmem 0x00011b00 humility: attached via DAPLink humility: reading at 0x11b00 for 256 bytes / 1 2 3 4 5 6 7 8 9 a b c d e f 0x00011b00 | 00 0f 1a bf 81 54 bc f1 01 0f d0 bd 02 44 bc f1 | .....T.......D.. 0x00011b10 | 02 0f 51 70 00 d1 d0 bd 91 70 d0 bd 69 00 01 00 | ..Qp.....p..i... 0x00011b20 | 04 00 00 00 04 00 00 00 17 01 01 00 6b 00 01 00 | ............k... 0x00011b30 | f1 00 01 00 65 78 70 6c 69 63 69 74 20 70 61 6e | ....explicit pan 0x00011b40 | 69 63 00 00 3c 1f 01 00 49 00 00 00 0a 00 00 00 | ic..<...I....... 0x00011b50 | 09 00 00 00 76 69 76 61 20 65 6c 20 6a 65 66 65 | ....viva el jefe 0x00011b60 | 0a 54 61 73 6b 20 23 20 50 61 6e 69 63 21 0a 00 | .Task # Panic!.. 0x00011b70 | 61 1b 01 00 06 00 00 00 67 1b 01 00 08 00 00 00 | a.......g....... 0x00011b80 | 20 42 61 64 20 53 79 73 63 61 6c 6c 20 55 73 61 | Bad Syscall Usa 0x00011b90 | 67 65 20 0a 61 1b 01 00 06 00 00 00 80 1b 01 00 | ge .a........... 0x00011ba0 | 13 00 00 00 93 1b 01 00 01 00 00 00 20 53 74 61 | ............ Sta 0x00011bb0 | 63 6b 20 6f 76 65 72 66 6c 6f 77 20 61 74 20 61 | ck overflow at a 0x00011bc0 | 64 64 72 65 73 73 20 30 78 00 00 00 61 1b 01 00 | ddress 0x...a... 0x00011bd0 | 06 00 00 00 ac 1b 01 00 1d 00 00 00 93 1b 01 00 | ................ 0x00011be0 | 01 00 00 00 20 4d 65 6d 6f 72 79 20 66 61 75 6c | .... Memory faul 0x00011bf0 | 74 20 61 74 20 61 64 64 72 65 73 73 20 30 78 00 | t at address 0x.

If an argument is present, it is the number of bytes to read:

$ humility readmem 0x00011d00 100 humility: attached via DAPLink humility: reading at 0x11d00 for 100 bytes / 1 2 3 4 5 6 7 8 9 a b c d e f 0x00011d00 | 20 62 6f 75 6e 64 73 3a 20 74 68 65 20 6c 65 6e | bounds: the len 0x00011d10 | 20 69 73 20 20 62 75 74 20 74 68 65 20 69 6e 64 | is but the ind 0x00011d20 | 65 78 20 69 73 20 30 30 30 31 30 32 30 33 30 34 | ex is 0001020304 0x00011d30 | 30 35 30 36 30 37 30 38 30 39 31 30 31 31 31 32 | 0506070809101112 0x00011d40 | 31 33 31 34 31 35 31 36 31 37 31 38 31 39 32 30 | 1314151617181920 0x00011d50 | 32 31 32 32 32 33 32 34 32 35 32 36 32 37 32 38 | 2122232425262728 0x00011d60 | 32 39 33 30 | 2930

Both arguments can be in either hex, decimal, octal or binary (addresses and contents will always be printed in hex):

humility readmem 0o216401 0b110 humility: attached via DAPLink humility: reading at 0x11d01 for 6 bytes 0 / 2 3 4 5 6 7 8 9 a b c d e f 0x00011d00 | 62 6f 75 6e 64 73 | bounds

The length argument can have an optional size suffix. Note that "k" is used to to denote the SI kilobytes (that is, 1000 bytes); if one wishes to have a multiples of 1024 bytes (a kibibyte), "KiB" should be used instead.

To display as half-words (16-bits) use -h; to display as words (32-bits) use -w. (The addresses must be 2-byte and 4-byte aligned, respectively.)

$ humility readmem -w 0x20000000 0x40 humility: attached via DAPLink humility: reading at 0x20000000 for 64 bytes / 4 8 c 0x20000000 | 00000001 20000180 0000000b 00005020 | ....... .... P.. 0x20000010 | 00000002 200001f0 00838042 00000000 | ....... B....... 0x20000020 | 00004db8 00004dc8 00004d28 00004d28 | .M...M..(M..(M.. 0x20000030 | 00004d28 00004d28 00004d28 00004d28 | (M..(M..(M..(M..

A frequent use of readmem is to read peripheral memory; as a convenience, a peripheral name can be used in lieu of an address, provided that an archive or dump is also specified:

$ humility -a ~/hubris/target/gemini-bu/dist/build-gemini-bu.zip readmem -w i2c4 0x30 humility: attached via ST-Link / 4 8 c 0x58001c00 | 000000f7 00020490 00008000 00008000 | ................ 0x58001c10 | 10c0ecff 00000000 00000021 00000000 | ........!....... 0x58001c20 | 00000000 00000080 00000000 00000000 | ................

Note that reading some peripheral memory may have side effects!

It can also be useful to interpret memory contents symbolically; to do this, provide a dump or achive and specify the -s option, e.g.:

$ humility -a ~/hubris/target/gemini-bu-rot/dist/build-gemini-bu-rot.zip readmem -s 0x20004b30 0x40 humility: attached via DAPLink 0x20004b30 | 0x20004bdc 0x20004b34 | 0x0000000a <- __EXCEPTIONS+0x2 0x20004b38 | 0x80000000 0x20004b3c | 0x00002e2e <- syscall_entry+0xcf6 0x20004b40 | 0x00000000 0x20004b44 | 0x0003c2e3 <- spi:main+0x5b 0x20004b48 | 0x0003ceda <- spi:sys_send_stub+0xe 0x20004b4c | 0x01000000 0x20004b50 | 0x00000000 0x20004b54 | 0x00000000 0x20004b58 | 0x00000000 0x20004b5c | 0x00000000 0x20004b60 | 0x00000000 0x20004b64 | 0x00000000 0x20004b68 | 0x00000000 0x20004b6c | 0x00000000

humility readvar

humility readvar allows one to read a global static variable. To list all such variables, use the -l option:

$ humility readvar -l humility: MODULE VARIABLE ADDR SIZE humility: kernel CORE_PERIPHERALS 0x20000000 1 humility: kernel CURRENT_TASK_PTR 0x20000018 4 humility: kernel DEVICE_PERIPHERALS 0x20000001 1 humility: kernel FAULT_NOTIFICATION 0x20000004 4 humility: kernel IRQ_TABLE_BASE 0x20000010 4 humility: kernel IRQ_TABLE_SIZE 0x20000014 4 humility: kernel TASK_TABLE_BASE 0x20000008 4 humility: kernel TASK_TABLE_SIZE 0x2000000c 4 humility: kernel __EXCEPTIONS 0x08000008 56 humility: kernel __INTERRUPTS 0x08000040 620 humility: kernel __RESET_VECTOR 0x08000004 4 humility: adt7420 TEMPS_BYMINUTE 0x2000b848 17288 humility: adt7420 TEMPS_BYSECOND 0x20008000 14408

To read a variable, specify it:

$ humility readvar CURRENT_TASK_PTR humility: attached via ST-Link CURRENT_TASK_PTR (0x20000018) = Some(NonNullkern::task::Task { pointer: 0x20000558 (*const kern::task::Task) })

humility rebootleby

Recovers an LPC55 target by reflashing the CFPA, CMPA, and bootleby image. This will not work if the target has a locked CMPA or SWD access has been disabled!

!!! Using this can be dangerous and should be undertaken with caution

humility registers

humility registers displays the registers from either a live system or a dump, e.g.:

$ humility registers humility: attached via ST-Link V3 R0 = 0x00000000 R1 = 0x0000000a R2 = 0x80000000 R3 = 0x00000000 R4 = 0x00000000 R5 = 0x0000f406 R6 = 0x00002711 R7 = 0x20000310 R8 = 0x00000000 R9 = 0x00000000 R10 = 0x20000f68 R11 = 0x00000001 R12 = 0x200002b4 SP = 0x200002e8 LR = 0x0800414f PC = 0x08004236 PSR = 0x4100000f <- 0100_0001_0000_0000_0000_0000_0000_1111 |||| | || | | | |||| | || | | + Exception = 0xf |||| | || | +------------ IC/IT = 0x0 |||| | || +-------------------- GE = 0x0 |||| | |+------------------------------ T = 1 |||| | +------------------------------- IC/IT = 0x0 |||| +--------------------------------- Q = 0 |||+----------------------------------- V = 0 ||+------------------------------------ C = 0 |+------------------------------------- Z = 1 +-------------------------------------- N = 0

MSP = 0x200002e8 PSP = 0x20011ab0 SPR = 0x01000001 <- 0000_0001_0000_0000_0000_0000_0000_0001 ||| | | | ||| | | + PRIMASK = 1 ||| | +---------- BASEPRI = 0x0 ||| +-------------------- FAULTMASK = 0 ||+------------------------------ CONTROL.nPRIV = 1 |+------------------------------- CONTROL.SPSEL = 0 +-------------------------------- CONTROL.FPCA = 0

FPSCR = 0x00000000

If an archive is provided or if displaying registers from a dump, the symbol that corresponds to register's value (if any) is displayed, e.g.:

$ humility -d ./hubris.core.81 registers humility: attached to dump R0 = 0x00000000 R1 = 0x0000000a R2 = 0x80000000 R3 = 0x00000000 R4 = 0x00000000 R5 = 0x0000f406 R6 = 0x00002711 R7 = 0x20000310 <- kernel: 0x20000000+0x310 R8 = 0x00000000 R9 = 0x00000000 R10 = 0x20000f68 <- kernel: DEVICE_PERIPHERALS+0x0 R11 = 0x00000001 R12 = 0x200002b4 <- kernel: 0x20000000+0x2b4 SP = 0x200002e8 <- kernel: 0x20000000+0x2e8 LR = 0x0800414f <- kernel: write_str<cortex_m::itm::Port>+0xd PC = 0x08004236 <- kernel: panic+0x36 PSR = 0x4100000f <- 0100_0001_0000_0000_0000_0000_0000_1111 |||| | || | | | |||| | || | | + Exception = 0xf |||| | || | +------------ IC/IT = 0x0 |||| | || +-------------------- GE = 0x0 |||| | |+------------------------------ T = 1 |||| | +------------------------------- IC/IT = 0x0 |||| +--------------------------------- Q = 0 |||+----------------------------------- V = 0 ||+------------------------------------ C = 0 |+------------------------------------- Z = 1 +-------------------------------------- N = 0

MSP = 0x200002e8 <- kernel: 0x20000000+0x2e8 PSP = 0x20011ab0 <- pong: 0x20011800+0x2b0 SPR = 0x01000001 <- 0000_0001_0000_0000_0000_0000_0000_0001 ||| | | | ||| | | + PRIMASK = 1 ||| | +---------- BASEPRI = 0x0 ||| +-------------------- FAULTMASK = 0 ||+------------------------------ CONTROL.nPRIV = 1 |+------------------------------- CONTROL.SPSEL = 0 +-------------------------------- CONTROL.FPCA = 0

To display a stack backtrace, use the --stack (-s) option:

$ humility -d ./hubris.core.81 registers --stack humility: attached to dump R0 = 0x00000000 ... R10 = 0x20000f68 <- kernel: DEVICE_PERIPHERALS+0x0 R11 = 0x00000001 R12 = 0x200002b4 <- kernel: 0x20000000+0x2b4 SP = 0x200002e8 <- kernel: 0x20000000+0x2e8 | +---> 0x20000318 0x08004236 rust_begin_unwind 0x20000330 0x08000558 core::panicking::panic_fmt 0x20000358 0x08000ad8 core::panicking::panic 0x20000390 0x08003ba6 kern::arch::arm_m::safe_sys_tick_handler 0x20000390 0x08003ba6 kern::arch::arm_m::SysTick::{{closure}} 0x20000390 0x08003ba6 kern::arch::arm_m::with_task_table 0x20000390 0x08003bb0 SysTick

LR = 0x0800414f <- kernel: write_str<cortex_m::itm::Port>+0xd ...

To additionally display floating point registers on platforms that support floating point, use the --floating-point (-f) option.

humility rencm

Query the Renesas 8A3400X ClockMatrix part -- or process a trace from Renesas configuration software.

humility rendmp

humility rendmp allows for querying, dumping and flashing the Renesas Digital Multiphase family of voltage regulators.

Like humility pmbus, a device can be specified in terms of an address (which requires the further specification of a controller and port) or a PMbus rail.

To view the number of NVM OTP slots that remain, use the --slotsoption:

$ humility rendmp -b mid -d 0x5a --slots humility: attached via ST-Link V3 humility: RAA229618 at I2C3, port H, dev 0x5a has 28 slots available

To determine the OTP CRC, use the --crc option. Note that an entirely unprogrammed part generally has a CRC of 0:

$ humility rendmp -b mid -d 0x5a --crc humility: attached via ST-Link V3 humility: RAA229618 at I2C3, port H, dev 0x5a has CRC 0x00000000

To flash a part (that is, to program its one-time programmable non-volatile memory), specify the HEX file as generated by the Renesas PowerNavigator. Note that this file specifies the address of the device; mismatches are not permitted, e.g.:

$ humility rendmp -b mid -d 0x5b --flash ./raa229618-0x5a.hex humility: attached via ST-Link V3 humility rendmp failed: image specifies address to be 0x5a; can't flash 0x5b

Specify the proper device to flash:

$ humility rendmp -b mid -d 0x5a --flash ./raa229618-0x5a.hex humility: attached via ST-Link V3 humility: 28 NVM slots remain humility: flashing 2871 bytes humiility: flashed 2.80KB in 4 seconds humility: bank 0: bank written successfully humility: flashed successfully after 246 ms; power cycle to load new configuration

To check a configuration, specify the image and the --check option:

$ humility rendmp -b mid -d 0x5c -f ./isl68224-0x5c.hex --check humility: attached via ST-Link V3 humility: 27 NVM slots remain humility: image CRC (0x841f35a5) matches OTP CRC

The Renesas voltage regulators include a black box which stores fault information. This can be queried using the --blackbox subcommand, specifying a device (I2C) address to pick a specific power converter:

$ humility rendmp --blackbox --device=0x5b humility: attached to 0483:374f:000C001F4D46500F20373033 via ST-Link V3 rail0 uptime: 0 sec rail1 uptime: 0 sec controller fault: 0 rail0 fault: 00000000000000000000000000000000 () rail1 fault: 00000000000000000000000000000000 () phase fault uc: 00000000000000000000000000000000 () phase fault oc: 00000000000000000000000000000000 () adc fault uc: 00000000000000000000000000000000 () adc fault oc: 00000000000000000000000000000000 () rail0 status: 0000000000000000 () rail1 status: 0000000000000000 () status cml: 00000000 () status mfr: 00000000 () rail1 status vout: 00000000 () rail0 status vout: 00000000 () rail1 status iout: 00000000 () rail0 status iout: 00000000 () rail1 status temperature: 00000000 () rail0 status temperature: 00000000 () rail1 status input: 00000000 () rail0 status input: 00000000 ()

 | RAIL 0  | RAIL 1

-----|---------|----------- VIN | 0.00 V | 0.00 V VOUT | 0.000 V | 0.000 V IIN | 0.00 A | 0.00 A IOUT | 0.0 A | 0.0 A TEMP | 0°C | 0°C controller read temperature: 0°C

PHASE TEMPERATURE CURRENT
0 0°C 0.0 A
1 0°C 0.0 A
2 0°C 0.0 A
3 0°C 0.0 A
4 0°C 0.0 A
5 0°C 0.0 A
6 0°C 0.0 A
7 0°C 0.0 A
8 0°C 0.0 A
9 0°C 0.0 A
10 0°C 0.0 A
11 0°C 0.0 A
12 0°C 0.0 A
13 0°C 0.0 A
14 0°C 0.0 A
15 0°C 0.0 A
16 0°C 0.0 A
17 0°C 0.0 A
18 0°C 0.0 A
19 0°C 0.0 A

(In the example above, there have been no faults so the blackbox is empty)

To check individual phases for errors, use the --phase-check subcommand:

$ humility rendmp --phase-check --device=0x5c humility: attached to 0483:3754:000D00344741500820383733 via ST-Link V3 Phase check for ISL68221 at 0x5c

PHASE VOUT IOUT TEMP RAIL
0 0.441V -56.100A 25.000°C VPP_ABCD
1 0.448V -55.800A 26.000°C VPP_EFGH
2 0.453V 0.900A 0.000°C V1P8_SP3

This must be run with the system in the A2 power state, and on a machine with no DIMMs. This latter constraint can be overridden with--force-phase-check, but this should be used carefully: if a checked phase powers a DIMM, an I2C hang can result.

humility repl

humility repl is an interactive prompt that you can use with humility.

This allows you to run several commands in succession without needing to type in some core settings over and over again.

humility repl takes the same top level arguments as any other subcommand, and will remember them inside of the prompt. For example:

$ humility -a ../path/to/hubris/archive.zip repl humility: attached via ST-Link V2-1 Welcome to the humility REPL! Try out some subcommands, or 'quit' to quit! humility> tasks system time = 7209837 ID TASK GEN PRI STATE 0 jefe 0 0 recv, notif: bit0 bit1(T+63) 1 rcc_driver 0 1 recv 2 usart_driver 0 2 RUNNING 3 user_leds 0 2 recv 4 ping 47524 4 wait: reply from usart_driver/gen0 5 pong 0 3 recv, notif: bit0(T+163) 6 hiffy 0 3 notif: bit31(T+121) 7 idle 0 5 ready

humility> tasks system time = 7212972 ID TASK GEN PRI STATE 0 jefe 0 0 recv, notif: bit0 bit1(T+28) 1 rcc_driver 0 1 recv 2 usart_driver 0 2 recv, notif: bit0(irq38) 3 user_leds 0 2 recv 4 ping 47544 4 RUNNING 5 pong 0 3 recv, notif: bit0(T+28) 6 hiffy 0 3 notif: bit31(T+252) 7 idle 0 5 ready

humility> quit Quitting!

As you can see, we can run the tasks subcommand twice, without passing our archive each time. In the output above, you can see the ping task faulting in the background; your code is still running in the background while you use the repl!

Finally, as you can see, quit will quit the repl. There is also ahistory command, which will show you recent commands you've put into the prompt.

The repl is still very early days! We'll be adding more features in the future.

humility reset

humility reset will hard reset the system using the debug pin or using software reset with the appropriate flag

humility ringbuf

humility ringbuf reads and displays any Hubris ring buffers (as created via the ringbuf! macro in the Hubris ringbuf crate). e.g.:

$ humility -d ./hubris.core.5 ringbuf ADDR NDX LINE GEN COUNT PAYLOAD 0x2000a288 552 92 1 5 (21.5, 70.69999694824219) 0x2000a298 553 92 1 1 (21.4375, 70.58749389648438) 0x2000a2a8 554 92 1 1 (21.5, 70.69999694824219) 0x2000a2b8 555 92 1 1 (21.4375, 70.58749389648438) 0x2000a2c8 556 92 1 5 (21.5, 70.69999694824219) 0x2000a2d8 557 92 1 1 (21.5625, 70.8125) 0x2000a2e8 558 92 1 15 (21.5, 70.69999694824219) 0x2000a2f8 559 92 1 1 (21.4375, 70.58749389648438) 0x2000a308 560 92 1 10 (21.5, 70.69999694824219) 0x2000a318 561 92 1 2 (21.4375, 70.58749389648438) 0x2000a328 562 92 1 2 (21.5, 70.69999694824219) 0x2000a338 563 92 1 1 (21.4375, 70.58749389648438) 0x2000a348 564 92 1 9 (21.5, 70.69999694824219) 0x2000a358 565 92 1 3 (21.4375, 70.58749389648438) 0x2000a368 566 92 1 4 (21.5, 70.69999694824219) 0x2000a378 567 92 1 1 (21.4375, 70.58749389648438) ...

If an argument is provided, only ring buffers that have a name that contains the argument as a substring, or are in a task that contains the argument as a substring will be displayed. For example, to display every ring buffer that has i2c in the name or the containing task:

$ humility -d ./hubris.core.76 ringbuf ksz humility: attached to dump humility: ring buffer ksz8463::__RINGBUF in net: NDX LINE GEN COUNT PAYLOAD 2 134 89 1 Read(IADR5, 0x4000) 3 134 89 1 Read(IADR4, 0x0) 4 134 89 1 Read(P1MBSR, 0x780c) 5 148 89 1 Write(IACR, 0x1c00) 6 134 89 1 Read(IADR5, 0x4000) 7 134 89 1 Read(IADR4, 0x0) 8 148 89 1 Write(IACR, 0x1c14) ...

By default, all integer values in a ring buffer are displayed in hex; this can be overridden with the --decimal option.

Unless explicitly disabled, ring buffer entries are de-deduplicated (with the count of a specific entry being indicated by the COUNT column). In some cases, it can be useful to expand these de-duplicated entries (for example, if each entry represents a measurement, and one wishes to see the entire series); this can be effected with the --expand option.

See the ringbufdocumentation for more details.

humility rpc

humility rpc allows for execution of Idol commands over a network, rather than through a debugger.

It requires the Hubris udprpc task to be listening on port 8. This task decodes bytes from a UDP packet, and shoves them directly into sys_send to a target task.

An archive is required so that humility knows what functions are available and how to call them. The archive ID is checked against the image ID on the target; udprpc will refuse to execute commands when the ID does not match.

Function calls are handled identically to the humility hiffy subcommand, except that an --ip address is required:

$ humility rpc --ip fe80::0c1d:9aff:fe64:b8c2%en0 -c UserLeds.led_on -aindex=0 UserLeds.led_on() = ()

Alternatively, you can set the HUMILITY_RPC_IP environmental variable.

You may need to configure an IPv6 network for humility rpc to work. On illumos, it looks like this:

$ pfexec ipadm create-addr -t -T addrconf e1000g0/addrconf

To listen for compatible devices on your network, run humility rpc --listen

$ humility rpc --listen humility: listening... (ctrl-C to stop, or timeout in 5s) MAC IPv6 COMPAT PART REV SERIAL a8:40:25:04:02:81 fe80::aa40:25ff:fe04:281 Yes 913-0000019 6 BRM42220066 a8:40:25:05:05:00 fe80::aa40:25ff:fe05:500 No (legacy) 0 (legacy) a8:40:25:05:05:00 fe80::aa40:25ff:fe05:501 No (legacy) 0 (legacy)

Under the hood, this listens for packets from the Hubris udpbroadcasttask, which includes MAC address and image ID (checked for compatibility). When listening, it is mandatory to specify the interface (e.g. humility rpc --listen -i en0 on MacOS). If the Part / Serial columns are marked as(legacy), the SP is running an older version of udpbroadcast that did not include identity information. If they are marked as (vpdfail), they are running a new-enough udpbroadcast, but the SP was unable to read its identity from its VPD.

To call all targets that match an archive, --listen can be combined with--call

humility sbrmi

Print out information retrieved via AMD's sideband remote management interface (SB-RMI). This interface is somewhat limited in its utility, but can sometimes yield information not available via other means.

When run without arguments, this will indicate the presence of each thread; if all are present and not in alert status, one will see output like:

THR 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf 0x00 ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok 0x10 ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok 0x20 ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok 0x30 ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok 0x40 ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok 0x50 ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok 0x60 ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok 0x70 ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok

If any CPU has its alert bit set, it will be marked as MCE, and the machine check exception information will be displayed, e.g.:

THR 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf 0x00 ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok 0x10 ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok 0x20 ok ok ok ok ok MCE ok ok ok ok ok ok ok ok ok ok 0x30 ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok 0x40 ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok 0x50 ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok 0x60 ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok 0x70 ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok ok

=== MCE on thread 0x25 (37), bank 0 ===

MCA_CTL(0)     0x0000000000ffffff
MCA_STATUS(0)  0xb420000001130839
               |
               +---> Valid (VAL)                         = true
                     Overflow (OVER)                     = false
                     Uncorrected error (UC)              = true
                     Error condition enabled (EN)        = true
                     Misc error register valid (MISCV)   = false
                     Address register valid (ADDRV)      = true
                     Processor context corrupt (PCC)     = false
                     Task content corrupt (TCC)          = false
                     Syndrome register valid (SYNDV)     = true
                     Deferred error (Deferred)           = false
                     Poisoned data consumed (Poison)     = false
                     Extended Error Code                 = 0x113
                     MCA Error Code                      = 0x839

MCA_ADDR(0)    0x000ffffe14700008
MCA_MISC(0)    0xd010000000000000
MCA_CONFIG(0)  0x00000007000001fd
               |
               +---> Interrupt Enable (IntEn)            = false
                     Deferred error type                 = 0x0
                     MCAX enable (McaxEn)                = true
                     MCA FRU text supported              = false
                     Address LSB in MCA_STATUS           = true
                     Deferred error status supported     = true
                     System fatal error event supported  = true
                     Deferred interrupt type supported   = true
                     Deferred error logging supported    = true
                     MCAX capable                        = true

MCA_SYND(0)    0x000000005c000002
MCA_IPID(0)    0x001000b000000000
               |
               +---> MCA bank type                       = 0x10
                     Instance ID (high)                  = 0x0
                     Hardware ID                         = 0xb0
                     Instance ID (low)                   = 0x0

MCA_DESTAT(0)  0x0000000000000000
MCA_DEADDR(0)  0x0000000000000000

CPU identification information as provided by the cpuid instruction can be retrieved by using the --cpuid option and specifying a desired target thread; full MCA information can similarly be retrieved using the --mca option and specifyin a desired thread.

humility sensors

humility sensors communicates with the sensor Hubris task via itsSensor Idol interface to get sensor data. If there is no sensor task or if there are no sensors defined in the in Hubris application description, this command will not provide any meaningful output. To list all available sensors, use -l (--list). To constrain sensors by type, use the -t (--types) option; to constrain sensors by device, use the-d (--devices) option; to constrain sensors by name, use the -n(--named) option. Within each option, multiple specifications serve as a logical OR (that is, (-d raa229618,tmp117 would yield all sensors from either device), but if multiple kinds of specifications are present, they serve as a logical AND (e.g., -t thermal -d raa229618,tmp117 would yield all thermal sensors from either device). Alternatively, sensors can be listed or queried by specifying the ID (or IDs) via -i (--id).

By default, humility sensors displays the value of each specified sensor and exits; to read values once per second, use the -s (--sleep) option. To print values as a table with individual sensors as columns,--tabular. In its default output (with one sensor per row), error counts are also displayed.

humility spctrl

humility spctrl runs commands on the RoT to control the SP.

You must run humility spctrl init before any other commands

$ humility spctrl init [Ok([])]

You can read/write memory on the SP via the RoT

$ humility spctrl -W read 0x08000000 64 humility: attached via CMSIS-DAP / 4 8 c 0x08000000 | 20000400 08000299 08003b6d 08004271 | ... ....m;..qB.. 0x08000010 | 08003c8d 08003ccd 08003cd3 00000000 | .<...<...<...... 0x08000020 | 00000000 00000000 00000000 0800398b | .............9.. 0x08000030 | 08003b6d 00000000 08003aa9 080039dd | m;.......:...9..

$ humility spctrl -W read 0x00000000 64 humility: attached via CMSIS-DAP / 4 8 c 0x00000000 | 3d0fbf49 991373d9 9107611c f6d84242 | I..=.s...a..BB.. 0x00000010 | 742397db c7c60242 decc7515 ce719848 | ..#tB....u..H.q. 0x00000020 | b2d2639e faf8049b e202de8c 2ae12025 | .c..........% .* 0x00000030 | f739ba6f 20067a60 310c4e08 e42eca28 | o.9.`z. .N.1(...

$ humility spctrl -W write 0x00000000 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88 humility: attached via CMSIS-DAP [Ok([])]

$ humility spctrl -W read 0x00000000 64 humility: attached via CMSIS-DAP / 4 8 c 0x00000000 | 44332211 88776655 9107611c f6d84242 | ."3DUfw..a..BB.. 0x00000010 | 742397db c7c60242 decc7515 ce719848 | ..#tB....u..H.q. 0x00000020 | b2d2639e faf8049b e202de8c 2ae12025 | .c..........% .* 0x00000030 | f739ba6f 20067a60 310c4e08 e42eca28 | o.9.`z. .N.1(...

humility spd

Scan for and read devices implementing Serial Presence Detect (SPD). When run without arguments, humility spd will display the SPD data as gathered and cached by the system:

$ humility spd humility: attached via ST-Link V3 ADDR MANUFACTURER PART WEEK YEAR 0 Micron Technology 36ASF8G72PZ-3G2E1 44 2021 1 Micron Technology 36ASF8G72PZ-3G2E1 44 2021 2 Micron Technology 36ASF8G72PZ-3G2E1 44 2021 3 Micron Technology 36ASF8G72PZ-3G2E1 44 2021 4 Micron Technology 36ASF8G72PZ-3G2E1 44 2021 5 Micron Technology 36ASF8G72PZ-3G2E1 44 2021 6 Micron Technology 36ASF8G72PZ-3G2E1 44 2021 7 Micron Technology 36ASF8G72PZ-3G2E1 44 2021 8 Micron Technology 36ASF8G72PZ-3G2E1 44 2021 9 Micron Technology 36ASF8G72PZ-3G2E1 44 2021 10 Micron Technology 36ASF8G72PZ-3G2E1 44 2021 11 Micron Technology 36ASF8G72PZ-3G2E1 44 2021 12 Micron Technology 36ASF8G72PZ-3G2E1 44 2021 13 Micron Technology 36ASF8G72PZ-3G2E1 44 2021 14 Micron Technology 36ASF8G72PZ-3G2E1 44 2021 15 Micron Technology 36ASF8G72PZ-3G2E1 44 2021

This performs no I2C reads, and because it operates on cached data, can be run postmortem.

To force an I2C read of a given SPD device, specify the desired bus in terms of either a named bus or controller/port/mux:

% humility spd -b mid humility: attached via ST-Link V3 ADDR MANUFACTURER PART WEEK YEAR 0 Micron Technology 36ASF8G72PZ-3G2E1 44 2021 1 Micron Technology 36ASF8G72PZ-3G2E1 44 2021 2 Micron Technology 36ASF8G72PZ-3G2E1 44 2021 3 Micron Technology 36ASF8G72PZ-3G2E1 44 2021 4 Micron Technology 36ASF8G72PZ-3G2E1 44 2021 5 Micron Technology 36ASF8G72PZ-3G2E1 44 2021 6 Micron Technology 36ASF8G72PZ-3G2E1 44 2021 7 Micron Technology 36ASF8G72PZ-3G2E1 44 2021

Note that a given bus can have up to 8 DIMMs on it.

To dump the entire contents of one more SPDs, use the --verbose (-v) option:

% humility spd --bus mid --address 5 --verbose humility: attached via ST-Link V3 ADDR MANUFACTURER PART WEEK YEAR 5 Micron Technology 36ASF8G72PZ-3G2E1 44 2021 | +----> 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 0x000 | 23 12 0c 01 86 31 00 08 00 60 00 03 08 0b 80 00 | #....1...`...... 0x010 | 00 00 05 0d f8 ff 02 00 6e 6e 6e 11 00 6e f0 0a | ........nnn..n.. 0x020 | 20 08 00 05 00 50 14 28 28 00 78 00 14 3c 00 00 | ....P.((.x..<.. 0x030 | 00 00 00 00 00 00 00 00 00 00 00 00 16 16 15 16 | ................ 0x040 | 03 16 03 16 03 16 03 16 0d 16 16 16 16 16 00 00 | ................ 0x050 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0x060 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0x070 | 00 00 00 00 00 00 9c 00 00 00 00 00 e7 00 fd a3 | ................ 0x080 | 31 11 61 19 00 86 9d 22 01 65 45 00 00 00 00 00 | 1.a....".eE..... 0x090 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0x0a0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0x0b0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0x0c0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0x0d0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0x0e0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0x0f0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 b8 ce | ................ 0x100 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0x110 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0x120 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0x130 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0x140 | 80 2c 06 21 44 32 52 c5 7e 33 36 41 53 46 38 47 | .,.!D2R.~36ASF8G 0x150 | 37 32 50 5a 2d 33 47 32 45 31 20 20 20 31 80 2c | 72PZ-3G2E1 1., 0x160 | 45 4a 41 41 42 4a 35 50 30 30 31 00 00 00 00 00 | EJAABJ5P001..... 0x170 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0x180 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0x190 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0x1a0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0x1b0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0x1c0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0x1d0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0x1e0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ 0x1f0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................

To dump a given SPD to a file, additionally provide the --output (-o) option and specify a desired output file:

% humility spd --bus mid --address 5 --output spd.5.out humility: attached via ST-Link V3 humility: wrote SPD data for address 5 as binary to spd.5.out

humility spi

humility spi can be used to read or write to attached SPI devices, (as defined in the application TOML).

The SPI peripheral (block) to be used can be specified with the--peripheral (-p) option. This should be a number that matches SPI peripheral number; if it is not specified (and there is only one SPI-controlling task found), the peripheral associated with that task will be assumed.

Because of the full duplex nature of SPI, bytes will always be written_and_ read; to actually write specific bytes, the bytes to be written should be specified via --write (-w). To report bytes read back,--read (-r) should be specified, along with the number of bytes via--nbytes (-n).

For example, to write the byte sequence 0x1, 0x0, 0x0 and then read 32 bytes (discarding the first three) from device 0 on SPI2:

$ humility spi -p 2 --nbytes 32 --write 0x1,0x0,0x0 --read --discard 3 humility: attached to 0483:374e:003C00174741500520383733 via ST-Link V3 humility: SPI master is spi2_driver / 1 2 3 4 5 6 7 8 9 a b c d e f 0x00000000 | 01 de aa 55 00 00 00 ff 06 00 00 00 1c 01 0b 00 | ...U............ 0x00000010 | 00 00 00 00 ff ff ff 06 12 00 00 00 06 | .............

humility stackmargin

humility stackmargin calculates and print stack margins by task. The margin is determined by walking up each stack, looking for the first word that does not contain the uninitialized pattern (0xbaddcafe), from which it infers maximum depth, and therefore margin:

$ humility -d ./hubris.core.10 stackmargin humility: attached to dump ID TASK STACKBASE STACKSIZE MAXDEPTH MARGIN 0 jefe 0x20001000 1024 768 256 1 rcc_driver 0x20001400 1024 176 848 2 usart_driver 0x20001800 1024 216 808 3 user_leds 0x20001c00 1024 208 816 4 ping 0x20002000 512 224 288 5 pong 0x20002400 1024 208 816 6 idle 0x20002800 256 104 152

Note that the margin is only valid for the task's lifetime -- and in particular, will not be correct if the task has restarted due to a stack overflow!

humility stmsecure

Humility has support to manage the Root Security Services (RSS) and various flash options bits

A typical sequence to set the secure region at 0x08000000

humility stmsecure set-secure-bit
humility stmsecure set-secure-region 0x08000000 0xa000

To undo the secure region:

humility stmsecure unset-secure-region
humility stmsecure unset-secure-bit

The STM32 has support for flash bank swapping as well

humility stmsecure bank-swap

humility tasks

humility tasks offers a ps-like view of a system, e.g.:

$ humility tasks humility: attached via ST-Link system time = 1764993 ID TASK GEN PRI STATE 0 jefe 0 0 recv, notif: bit0 bit1(T+7) 1 rcc_driver 0 1 recv 2 gpio_driver 0 2 recv 3 usart_driver 0 2 recv, notif: bit0(irq39) 4 i2c_driver 0 2 recv 5 spi_driver 0 2 recv 6 user_leds 0 2 recv 7 pong 0 3 FAULT: killed by jefe/gen0 (was: recv, notif: bit0) 8 ping 14190 4 wait: send to pong/gen0 9 hiffy 0 3 notif: bit0(T+7) 10 hf 0 3 notif: bit0(T+18) 11 idle 0 5 RUNNING

To see every field in each task, you can use the -v flag:

$ humility -d hubris.core.4 tasks -v humility: attached to dump system time = 1791860 ID TASK GEN PRI STATE ... 7 pong 0 3 FAULT: killed by jefe/gen0 (was: recv, notif: bit0) | +-----------> Task { save: SavedState { r4: 0x200063c4, r5: 0x10, r6: 0x1, r7: 0x0, r8: 0x60003, r9: 0x4, r10: 0x200063d4, r11: 0x1, psp: 0x20006330, exc_return: 0xffffffed, ... }, priority: Priority(0x3), state: Faulted { fault: Injected(TaskId(0x0)), original_state: InRecv(None) }, ... ...

To see a task's registers, use the -r flag:

$ humility tasks -r user_leds humility: attached via ST-Link system time = 1990498 ID TASK GEN PRI STATE 6 user_leds 0 2 recv | +---> R0 = 0x20005fc8 R1 = 0x0000000c R2 = 0x00000000 R3 = 0x20005fd8 R4 = 0x20005fc8 R5 = 0x0000000c R6 = 0x00000000 R7 = 0x00000000 R8 = 0x08027154 R9 = 0x00000000 R10 = 0xfffffe00 R11 = 0x00000001 R12 = 0x00000000 SP = 0x20005fa0 LR = 0x08026137 PC = 0x08026e42

To see a task's stack backtrace, use the -s flag:

$ humility tasks -s user_leds humility: attached via ST-Link system time = 2021382 ID TASK GEN PRI STATE 6 user_leds 0 2 recv | +---> 0x20005fc0 0x08026e42 userlib::sys_recv_stub 0x20006000 0x08026128 userlib::sys_recv 0x20006000 0x08026128 idol_runtime::dispatch 0x20006000 0x08026136 main

To additionally see line number information on a stack backtrace, also provide-l flag:

$ humility tasks -sl user_leds humility: attached via ST-Link system time = 2049587 ID TASK GEN PRI STATE 6 user_leds 0 2 recv | +---> 0x20005fc0 0x08026e42 userlib::sys_recv_stub @ /home/bmc/hubris/sys/userlib/src/lib.rs:288 0x20006000 0x08026128 userlib::sys_recv @ /home/bmc/hubris/sys/userlib/src/lib.rs:236 0x20006000 0x08026128 idol_runtime::dispatch @ /home/bmc/.cargo/git/checkouts/idolatry-1ebf1c2fd2f30300/6d18e14/runtime/src/lib.rs:137 0x20006000 0x08026136 main @ /home/bmc/hubris/drv/user-leds/src/main.rs:110

These options can naturally be combined, e.g. humility tasks -slvr.

humility test

When run against a test archive, humility test kicks off the test suite. Humility is responsible for getting the number of tests and then running each one in succession.

humility: attached via CMSIS-DAP Total test cases: 50 humility: running test_send ...ok humility: running test_recv_reply ...ok humility: running test_recv_reply_fault ...ok humility: running test_floating_point_lowregs ...ok humility: running test_floating_point_highregs ...ok humility: running test_floating_point_fault ...ok humility: running test_fault_badmem ...ok humility: running test_fault_stackoverflow ...ok humility: running test_fault_execdata ...ok humility: running test_fault_illop ...ok humility: running test_fault_nullexec ...ok humility: running test_fault_textoob ...ok humility: running test_fault_stackoob ...ok humility: running test_fault_buserror ...ok humility: running test_fault_illinst ...ok humility: running test_fault_divzero ...ok humility: running test_fault_maxstatus ...ok humility: running test_fault_badstatus ...ok humility: running test_fault_maxrestart ...ok humility: running test_fault_badrestart ...ok humility: running test_fault_maxinjection ...ok humility: running test_fault_badinjection ...ok humility: running test_fault_superinjection ...ok humility: running test_fault_selfinjection ...ok humility: running test_panic ...ok humility: running test_restart ...ok humility: running test_restart_taskgen ...ok humility: running test_borrow_info ...ok humility: running test_borrow_read ...ok humility: running test_borrow_write ...ok humility: running test_borrow_without_peer_waiting ...ok humility: running test_supervisor_fault_notification ...ok humility: running test_timer_advance ...ok humility: running test_timer_notify ...ok humility: running test_timer_notify_past ...ok humility: running test_task_config ...ok humility: running test_task_status ...ok humility: running test_task_fault_injection ...ok humility: running test_refresh_task_id_basic ...ok humility: running test_refresh_task_id_off_by_one ...ok humility: running test_refresh_task_id_off_by_many ...ok humility: running test_post ...ok humility: running test_idol_basic ...ok humility: running test_idol_bool_arg ...ok humility: running test_idol_bool_ret ...ok humility: running test_idol_bool_xor ...ok humility: running test_idol_err_ret ...ok humility: running test_idol_ssmarshal ...ok humility: running test_idol_ssmarshal_multiarg ...ok humility: running test_idol_ssmarshal_multiarg_enum ...ok Ran a total of 50 cases

All tests will produce an output file. This contains information about the hubris archive as well as task state after each test run. Search for "fail" to see any failed tests.

$ cat hubris.testout.15 ... ==== Test results ... ==== Test test_task_status result: "ok" ==== Task state system time = 27941 ID TASK GEN PRI STATE 0 runner 0 0 recv, notif: bit0 bit1 bit2 bit3 bit4 bit5 bit6 bit7 bit8 bit9 bit10 bit11 bit12 bit13 bit14 bit15 bit16 bit17 bit18 bit19 bit20 bit21 bit22 bit23 bit24 bit25 bit26 bit27 bit28 bit29 bit30 bit31 1 suite 33 2 recv 2 assist 37 1 FAULT: in syscall: used bogus task index (was: ready) 3 idol 0 1 recv 4 hiffy 0 3 notif: bit31(T+8) 5 idle 0 4 RUNNING

Older versions of the test suite gave streaming output. This is no longer available. If the information in the output is not enough to debug, the recommendation is to extend the state that is captured.

humility tofino-eeprom

Tools to interact with the Tofino EEPROM

humility validate

humility validate uses the Hubris validate task to validate the correct presence of devices as described by the application TOML. To view all devices, use the --list option; to validate them, run without any additional arguments:

$ humility validate humility: attached via ST-Link V3 ID VALIDATION C P MUX ADDR DEVICE DESCRIPTION 0 removed 2 F - 0x48 tmp117 Southwest temperature sensor 1 removed 2 F - 0x49 tmp117 South temperature sensor 2 removed 2 F - 0x4a tmp117 Southeast temperature sensor 3 present 2 F - 0x70 pca9545 U.2 ABCD mux 4 present 2 F - 0x71 pca9545 U.2 EFGH mux 5 present 2 F - 0x72 pca9545 U.2 IJ/FRUID mux 6 timeout 2 B - 0x73 pca9545 M.2 mux 7 timeout 2 B 1:4 0x4c tmp451 T6 temperature sensor 8 validated 3 H - 0x24 tps546b24a A2 3.3V rail 9 validated 3 H - 0x26 tps546b24a A0 3.3V rail 10 validated 3 H - 0x27 tps546b24a A2 5V rail 11 validated 3 H - 0x29 tps546b24a A2 1.8V rail 12 present 3 H - 0x3a max5970 M.2 hot plug controller 13 absent 3 H - 0x4c sbtsi CPU temperature sensor 14 present 3 H - 0x58 idt8a34003 Clock generator 15 validated 3 H - 0x5a raa229618 CPU power controller 16 validated 3 H - 0x5b raa229618 SoC power controller 17 validated 3 H - 0x5c isl68224 DIMM/SP3 1.8V A0 power controller 18 validated 4 F - 0x10 adm1272 Fan hot swap controller 19 validated 4 F - 0x14 adm1272 Sled hot swap controller 20 validated 4 F - 0x20 max31790 Fan controller 21 validated 4 F - 0x25 tps546b24a T6 power controller 22 removed 4 F - 0x48 tmp117 Northeast temperature sensor 23 removed 4 F - 0x49 tmp117 North temperature sensor 24 validated 4 F - 0x4a tmp117 Northwest temperature sensor 25 validated 4 F - 0x67 bmr491 Intermediate bus converter

humility vpd

Reads from (or writes to) EEPROMs that contain vital product data (VPD). To list all eligible devices, use --list:

$ humility vpd --list humility: attached via ST-Link V3 ID C P MUX ADDR DEVICE DESCRIPTION LOCKED 0 1 B 1:1 0x50 at24csw080 Sharkfin VPD locked 1 1 B 1:2 0x50 at24csw080 Gimlet Fan VPD unlocked 2 1 B 1:3 0x50 at24csw080 Sidecar Fan VPD unlocked

To read from all devices, combine --list with --read. To read from a particular device, use --read alone, and specify the device by either id (--id) or by some (case-insensitive) substring of its description (--device):

$ humility vpd --read --id 0 humility: attached via ST-Link V3 [ ("FRU0", [ ("BARC", [ "OXC11R00241", ]), ]), ]

In this example, this could also be phrased as:

$ humility vpd --read --device sharkfin humility: attached via ST-Link V3 [ ("FRU0", [ ("BARC", [ "OXC11R00241", ]), ]), ]

You can also use the --raw flag to --read to see the raw bytes:

$ humility vpd --read -i 10 --raw humility: attached via ST-Link V3 / 1 2 3 4 5 6 7 8 9 a b c d e f 0x00000000 | 46 52 55 30 4c 00 00 00 fd c6 3b db 42 41 52 43 | FRU0L.....;.BARC 0x00000010 | 1f 00 00 00 ce 3d d7 f7 30 58 56 31 3a 39 31 33 | .....=..0XV1:913 0x00000020 | 30 30 30 30 30 31 39 3a 30 30 36 3a 42 52 4d 34 | 0000019:006:BRM4 0x00000030 | 32 32 32 30 30 32 33 00 b9 1f 7f e3 4d 41 43 30 | 2220023.....MAC0 0x00000040 | 09 00 00 00 61 64 d1 7e a8 40 25 04 01 00 08 00 | ....ad.~.@%..... 0x00000050 | 08 00 00 00 26 27 3d 9d ee a4 f9 bb ff ff ff ff | ....&'=.........

Note that this will fail if the description matches more than one device, e.g.:

$ humility vpd --read --device fan humility: attached via ST-Link V3 humility vpd failed: multiple devices match description "fan"

To write VPD data, pass a filename of a file that contains a RON description of a valid TLV-C payload, e.g.:

$ cat vpd.in [("BARC", [ ("FOOB", [ [8, 6, 7, 5, 3, 0, 9] ]), ("QUUX", []), ])] $ humility vpd --write ./vpd.in --device sharkfin humility: attached via ST-Link V3 humility: successfully wrote 56 bytes of VPD

You can also use a file as a loopback device via --loopback, allowing you to, e.g., read binary data and format it (i.e., via --read).

To lock a VPD device, use the --lock command. This will lock the VPD permanently and cannot be undone; subsequent attempts to write to (or lock) a locked VPD device will result in an error. The lock status of each device is shown in --list.

To lock all VPD devices, use the --lock-all command. This will exit successfully if all devices were successfully locked or are already locked; if a device is missing or otherwise cannot be locked, all other devices will be locked, but the command will exit with a non-zero exit status.

humility writeword

Given a word-aligned address, writes the specified 32-bit value. If multiple values are specified, writes each in turn, incrementing the address by the word size after each write.

**It should go without saying that this should be only used with care.**In particular, the target is not halted before any writes (but that functionality can be affected by using writeword).

For example, to write the value 0x11223344 to 0x24018900:

$ humility writeword 0x24018900 0x11223344 humility: attached via ST-Link V3 humility: writing 0x11223344 to 0x24018900

Note that the word is written as single, 32-bit value -- and will therefore be little-endian if reading memory:

$ humility readmem 0x24018900 16 humility: attached via ST-Link V3 / 1 2 3 4 5 6 7 8 9 a b c d e f 0x24018900 | 44 33 22 11 00 00 00 00 00 00 00 00 00 00 00 00 | D3".............

To write multiple values to multiple words starting at the specified address, specify them as additional arguments, e.g.:

$ humility writeword 0x24047800 0xaa 0xbb 0xcc 0xdd humility: attached via ST-Link V3 humility: writing 0xaa to 0x24047800 humility: writing 0xbb to 0x24047804 humility: writing 0xcc to 0x24047808 humility: writing 0xdd to 0x2404780c $ humility readmem 0x24047800 16 humility: attached via ST-Link V3 / 1 2 3 4 5 6 7 8 9 a b c d e f 0x24047800 | aa 00 00 00 bb 00 00 00 cc 00 00 00 dd 00 00 00 | ................