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}"
+}