Add nexus helper functions to build Change-Id: Icdb3599ea8f0cc4f1ce5b7180a03b5757f725cb9
diff --git a/platforms/nexus/setup.sh b/platforms/nexus/setup.sh index c6275e5..578b466 100644 --- a/platforms/nexus/setup.sh +++ b/platforms/nexus/setup.sh
@@ -45,6 +45,11 @@ # Input for topgen_matcha.py to generate hw configuration export TOP_MATCHA_HJSON="${ROOTDIR}/hw/matcha/hw/top_matcha/data/top_matcha.hjson" +# Standard locations of Nexus configs and binaries +export OT_TOOL="${ROOTDIR}/out/opentitantool" +export NEXUS_JSON="${ROOTDIR}/out/nexus.json" +export NEXUS_SPI_PASSTHRU="${ROOTDIR}/out/spi_passthrough_fpga_nexus.bin" + function parting_messages() { if [[ ! -d "${RUSTDIR}" ]] || [[ ! -d "${ROOTDIR}/cache/toolchain" ]] || @@ -61,13 +66,14 @@ [[ -d "${ROOTDIR}/cache/toolchain_iree_rv32imf" ]] || echo "${ROOTDIR}/cache/toolchain_iree_rv32imf is missing!" [[ -d "${ROOTDIR}/cache/renode" ]] || echo "${ROOTDIR}/cache/renode is missing!" fi + echo Run \'set-nexus-id NN\' to set your Nexus board ID } function sim_kelvin { # Run the ELF/Bin program with kelvin_sim - local bin_file=$(realpath $1) - local magic_bytes=$(xxd -p -l 4 "${bin_file}") + local bin_file="$(realpath $1)" + local magic_bytes="$(xxd -p -l 4 ${bin_file})" local -a flags=() local is_elf=false if [[ ${magic_bytes} == "7f454c46" ]]; then @@ -90,7 +96,7 @@ function sim_kelvin_renode { # Run the Bin program with renode - local bin_file=$(realpath $1) + local bin_file="$(realpath $1)" local command="start;" (cd "${ROOTDIR}" && renode -e "\$bin=@${bin_file}; i @sim/config/kelvin.resc; \ @@ -98,3 +104,196 @@ --disable-xwt --console) } + +function set-nexus-id +{ + local nexus_id="${1}"; shift + + if [[ -z "${nexus_id}" ]]; then + ( + echo "Usage: set-nexus-id <NN>" + echo + echo "Sets the target Nexus board to run on. Must be a two digit number" + echo + ) | fmt + return 1 + fi + if [[ "${#nexus_id}" -ne 2 ]]; then + echo "Nexus number must be two digits" + return 1 + fi + + export NEXUS_ID="${nexus_id}" + # TODO(b/316200811) track down all the places we use a different variable name: + export NEXUS_BOARD="${nexus_id}" + export FPGA_BOARD_ID="${nexus_id}" +} + +function opentitantool +{ + # Run built opentitantool with standard flags + if [[ -z "${NEXUS_ID}" ]]; then + echo "Run set-nexus-id first" + return 1 + fi + + "${OT_TOOL}" --conf "${NEXUS_JSON}" --interface nexus --usb-serial \ + "Nexus-FTDI-${NEXUS_ID}" "$@" +} + +function nexus_reset +{ + # Reset nexus board + if [[ -z "${NEXUS_ID}" ]]; then + echo "Run set-nexus-id first" + return 1 + fi + + opentitantool gpio write RESET true + opentitantool gpio write RESET false + opentitantool gpio write RESET true +} + +function nexus_flash +{ + # Write tar file to nexus SPI flash and verify + + local flash_tar="$(realpath $1)" + if [[ -z "${flash_tar}" ]]; then + ( + echo "Usage: nexus_flash path/to/file.tar" + echo + echo "Writes tar file to Nexus SPI flash for booting." + echo + ) | fmt + return 1 + fi + + if [[ -z "${NEXUS_ID}" ]]; then + echo "Run set-nexus-id first" + return 1 + fi + + if [[ ! -f "${NEXUS_SPI_PASSTHRU}" ]]; then + echo "INFO: spi_passthrough binary not found at ${NEXUS_SPI_PASSTHRU}" + echo "running `m spi_passthrough` to build it" + m spi_passthrough + if [[ "$?" -ne 0 ]]; then + echo "ERROR: Unable to find or build spi_passthrough!" + return 1 + fi + fi + + nexus_reset + + local read_size="$(du -b ${flash_tar} | awk '{print $1}')" + local erase_size="$(du -b ${flash_tar} \ + | awk '{ print $1 + (n - $1 % n) % n }' n=262144)" + + echo "Program SPI using ${NEXUS_SPI_PASSTHRU} on board ${NEXUS_ID}" + opentitantool bootstrap "${NEXUS_SPI_PASSTHRU}" + opentitantool spi block-erase --start 0 --length "${erase_size}" + opentitantool spi program --start 0 "${flash_tar}" + + local readback_file="$(mktemp -d)/$(basename ${flash_tar}).readback" + opentitantool spi read --start 0 --length "${read_size}" "${readback_file}" + diff "${flash_tar}" "${readback_file}" + if [[ "$?" -ne 0 ]]; then + echo "ERROR: Nexus flash verify failed!" + return 1 + fi + rm "${readback_file}" + + nexus_reset +} + +function nexus_clear_flash +{ + # Clear the first page of the SPI flash to prevent restarting from the + # loaded program at the next reset. + if [[ -z "${NEXUS_ID}" ]]; then + echo "Run set-nexus-id first" + return 1 + fi + + echo "Clearing nexus SPI flash" + nexus_reset + opentitantool bootstrap "${NEXUS_SPI_PASSTHRU}" + opentitantool spi block-erase --start 0 --length 262144 +} + +function nexus_mcu_write() { + # Slowly send characters to the Nexus MCU + if [[ -z "${NEXUS_ID}" ]]; then + echo "Run set-nexus-id first" + return 1 + fi + + local string="$1" + local length="${#string}" + for ((i = 0; i < length; i++)); do + local char="${string:i:1}" + echo -n "$char" > "/dev/Nexus-FTDI-${NEXUS_ID}-MCU-UART" + sleep 0.5 + done + echo -e "\r" > "/dev/Nexus-FTDI-${NEXUS_ID}-MCU-UART" +} + +function nexus_load_bitstream +{ + # Load bitstream file onto Nexus FPGA + local bitstream_path="$(realpath 1)" + if [[ -z "${bitstream_path}" ]]; then + ( + echo "Usage: nexus_load_bitstream path/to/file.bit" + echo + echo "Loads bitstream file onto Nexus FPGA" + echo "This command may ask you for the Nexus SOM root password" + echo + ) | fmt + return 1 + fi + + if [[ -z "${NEXUS_ID}" ]]; then + echo "Run set-nexus-id first" + return 1 + fi + + if [[ ! -f "${bitstream_path}" ]]; then + echo "ERROR: bitstream not found at ${bitstream_path}" + return 1 + fi + + # Issue a no-op command to flush the character buffer in case it isn't empty + nexus_mcu_write "help" + scp "${bitstream_path}" "root@nexus${NEXUS_ID}:/mnt/mmcp1/" + nexus_mcu_write "camera_powerdown" + sleep 5 + local bitstream_name="$(basename ${bitstream_path})" + ssh "root@nexus${NEXUS_ID}" "/mnt/mmcp1/zturn -d a /mnt/mmcp1/${bitstream_name}" + nexus_mcu_write "camera_powerup" +} + +function nexus_boot +{ + # Boot the Nexus board. If flashed, will boot from flash + # This command is a synomym for `opentitantool boot` + opentitantool boot +} + +function nexus_bootstrap +{ + # Bootstrap a binary on the Nexus board + + local binary="$(realpath $1)" + if [[ -z "${binary}" ]]; then + ( + echo "Usage: nexus_flash path/to/file.bin" + echo + echo "Run a binary on the nexus board." + echo + ) | fmt + return 1 + fi + opentitantool bootstrap "${binary}" +}