From fb9aefca1f7e4ec7408a9e0e916f4ccaaa8750af Mon Sep 17 00:00:00 2001 From: Lauren Murphy Date: Mon, 6 Mar 2023 14:24:35 -0800 Subject: [PATCH] boards: intel_adsp: unify and update docs Unifies docs into one updated guide with stubs for each platform. Signed-off-by: Lauren Murphy --- boards/xtensa/index.rst | 2 +- .../intel_adsp_ace15_mtpm/doc/index.rst | 35 ++ boards/xtensa/intel_adsp_cavs15/doc/index.rst | 164 +------ .../doc/generic_intel_adsp.rst | 307 ------------- boards/xtensa/intel_adsp_cavs18/doc/index.rst | 34 ++ .../doc/chromebooks_adsp.rst | 417 +++++++++++++++++ boards/xtensa/intel_adsp_cavs25/doc/index.rst | 427 +----------------- .../doc/intel_adsp_generic.rst | 340 ++++++++++++++ 8 files changed, 871 insertions(+), 855 deletions(-) create mode 100644 boards/xtensa/intel_adsp_ace15_mtpm/doc/index.rst delete mode 100644 boards/xtensa/intel_adsp_cavs18/doc/generic_intel_adsp.rst create mode 100644 boards/xtensa/intel_adsp_cavs18/doc/index.rst create mode 100644 boards/xtensa/intel_adsp_cavs25/doc/chromebooks_adsp.rst create mode 100644 boards/xtensa/intel_adsp_cavs25/doc/intel_adsp_generic.rst diff --git a/boards/xtensa/index.rst b/boards/xtensa/index.rst index 9bfc2e2384dca6..dd09c5df5b4f9e 100644 --- a/boards/xtensa/index.rst +++ b/boards/xtensa/index.rst @@ -7,4 +7,4 @@ XTENSA Boards :maxdepth: 1 :glob: - **/* + **/index diff --git a/boards/xtensa/intel_adsp_ace15_mtpm/doc/index.rst b/boards/xtensa/intel_adsp_ace15_mtpm/doc/index.rst new file mode 100644 index 00000000000000..d31783cd944afd --- /dev/null +++ b/boards/xtensa/intel_adsp_ace15_mtpm/doc/index.rst @@ -0,0 +1,35 @@ +.. _intel_adsp_ace15: + +Intel ADSP ACE 1.5 +################## + +Overview +******** + +This board configuration is used to run Zephyr on the Intel ACE 1.5 Audio DSP. +This configuration is present, for example, on Intel Meteor Lake microprocessors. +Refer to :ref:`intel_adsp_generic` for more details on Intel ADSP ACE and CAVS. + +System requirements +******************* + +Xtensa Toolchain +---------------- + +If you choose to build with the Xtensa toolchain instead of the Zephyr SDK, set +the following environment variables specific to the board in addition to the +Xtensa toolchain environment variables listed in :ref:`intel_adsp_generic`. + +.. code-block:: shell + + export ZEPHYR_TOOLCHAIN_VARIANT=xt-clang + export TOOLCHAIN_VER=RI-2021.7-linux + export XTENSA_CORE=ace10_LX7HiFi4 + +For older versions of the toolchain, set the toolchain variant to ``xcc``. + +Programming and Debugging +************************* + +Refer to :ref:`intel_adsp_generic` for generic instructions on programming and +debugging applicable to all CAVS and ACE platforms. diff --git a/boards/xtensa/intel_adsp_cavs15/doc/index.rst b/boards/xtensa/intel_adsp_cavs15/doc/index.rst index b0ed42e091b68c..42b9a58c4e4f13 100644 --- a/boards/xtensa/intel_adsp_cavs15/doc/index.rst +++ b/boards/xtensa/intel_adsp_cavs15/doc/index.rst @@ -1,156 +1,34 @@ -.. _Up_Squared_Audio_DSP: +.. _intel_adsp_cavs15: -Up Squared Audio DSP -#################### +Intel ADSP CAVS 1.5 +################### -System Requirements -******************* - -Prerequisites -============= - -The Zephyr SDK 0.11 or higher is required. - -Since firmware binary signing for Audio DSP is mandatory on Intel products -form Skylake onwards the signing tool and key are needed. - -``up_squared`` board is running Linux with `SOF Diagnostic Driver`_ built and -loaded. - -Signing tool ------------- +Overview +******** -rimage is Audio DSP firmware image creation and signing tool. The tool is used -by `Sound Open Firmware`_ to generate binary firmware signed images. +This board configuration is used to run Zephyr on the Intel CAVS 1.5 Audio DSP. +This configuration is present, for example, on Intel `Apollo Lake`_ microprocessors. +Refer to :ref:`intel_adsp_generic` for more details on Intel ADSP ACE and CAVS. -For the building instructions refer to `rimage Build Instructions`_. - -Signing keys ------------- - -The key used is Intel Open Source Technology Center (OTC) community key. -It can be freely used by anyone and intended for firmware developers. -Please download and store private key from the location: -https://github.com/thesofproject/sof/blob/master/keys/otc_private_key.pem +System requirements +******************* -For more information about keys refer to `rimage keys`_. +Xtensa Toolchain +---------------- -Setup up_squared board ----------------------- +If you choose to build with the Xtensa toolchain instead of the Zephyr SDK, set +the following environment variables specific to the board in addition to the +Xtensa toolchain environment variables listed in :ref:`intel_adsp_generic`. -To setup Linux on ``up_squared`` board refer to -`Getting Started with Ubuntu Core on an UP Squared Board`_. +.. code-block:: shell -After installing Linux build and install `SOF Diagnostic Driver`_. + export TOOLCHAIN_VER=RG-2017.8-linux + export XTENSA_CORE=X4H3I16w2D48w3a_2017_8 Programming and Debugging ************************* -Build Zephyr application -======================== - -Applications can be build in the usual way (see :ref:`build_an_application` -for more details). The only additional step required is signing. For example, -for building ``hello_world`` application following steps are needed. - -#. Building Zephyr application ``hello_world`` - - .. zephyr-app-commands:: - :zephyr-app: samples/hello_world - :board: intel_adsp_cavs15 - :goals: build - -#. Sign and create firmware image - - .. code-block:: console - - west sign -t rimage -- -k - -Loading image to Audio DSP -========================== - -`SOF Diagnostic Driver`_ provide interface for firmware loading. Python tools -in the board support directory use the interface to load firmware to ``ADSP``. - -Assume that the up_squared board's host name is ``cavs15`` (It also can be an -ip address), and the user account is ``user``. Then copy the python tool to the -``up_squared`` board from your build environment:: - - $ scp boards/xtensa/intel_adsp/tools/cavstool.py user@cavs15: - $ scp boards/xtensa/intel_adsp/tools/remote-fw-service.py user@cavs15: - - -Note that the ``/dev/hda`` device file created by the diagnostic driver must -be readable and writable by the process. So we simply by running the -loader script as root: - -.. code-block:: console - - cavs15$ sudo ./remote-fw-service.py - -Cavstool_server.py is a daemon which accepts a firmware image from a remote host -and loads it into the ADSP. After successful firmware download, the daemon also -sends any log messages or output back to the client. - -Running and Debugging -===================== - -While the python script is running on ``up_squared`` board, you can start load -image and run the application by: - -.. code-block:: console - - west flash --remote-host cavs15 - -or - -.. code-block:: console - - west flash --remote-host 192.168.x.x --pty - -Then you can see the log message immediately: - -.. code-block:: console - - Hello World! intel_adsp_cavs15 - - -Integration Testing With Twister -================================ - -The ADSP hardware also has integration for testing using the twister -tool. The ``cavstool_client.py`` script can be used as the -``--device-serial-pty`` handler, and the west flash script should take -a path to the same key file used above. - -.. code-block:: console - - ./scripts/twister --device-testing -p intel_adsp_cavs15 \ - --device-serial-pty $ZEPHYR_BASE/soc/xtensa/intel_adsp/tools/cavstool_client.py,myboard.local,-l \ - --west-flash "--remote-host=myboard.local" - -And if you install the SOF software stack in rather than the default path, -you also can specify the location of the rimage tool, signing key and the -toml config, for example: - -.. code-block:: console - - ./scripts/twister --device-testing -p intel_adsp_cavs15 \ - --device-serial-pty $ZEPHYR_BASE/soc/xtensa/intel_adsp/tools/cavstool_client.py,myboard.local,-l \ - --west-flash "--remote-host=myboard.local,\ - --rimage-tool=/path/to/rimage_tool,\ - --key=/path/to/otc_private_key.pem,\ - --config-dir=/path/to/config_dir" - - -.. target-notes:: - -.. _Getting Started with Ubuntu Core on an UP Squared Board: https://software.intel.com/en-us/articles/getting-started-with-ubuntu-core-on-an-up-squared-board - -.. _SOF Diagnostic Driver: https://github.com/thesofproject/sof-diagnostic-driver - -.. _Sound Open Firmware: https://github.com/thesofproject/sof - -.. _rimage Build Instructions: https://github.com/thesofproject/rimage#building +Refer to :ref:`intel_adsp_generic` for generic instructions on programming and +debugging applicable to all CAVS and ACE platforms. -.. _rimage keys: https://github.com/thesofproject/sof/tree/master/rimage/keys +.. _Apollo Lake: https://www.intel.com/content/www/us/en/products/platforms/details/apollo-lake.html diff --git a/boards/xtensa/intel_adsp_cavs18/doc/generic_intel_adsp.rst b/boards/xtensa/intel_adsp_cavs18/doc/generic_intel_adsp.rst deleted file mode 100644 index a8493b10edd5b7..00000000000000 --- a/boards/xtensa/intel_adsp_cavs18/doc/generic_intel_adsp.rst +++ /dev/null @@ -1,307 +0,0 @@ -.. _Intel_Adsp_Generic_Running_Guide: - -Intel Adsp Generic Running Guide -################################ - -This documentation describes how to run the intel_adsp_cavs boards. Including: - -- intel_adsp_cavs15 - -- intel_adsp_cavs18 - -- intel_adsp_cavs20 - -- intel_adsp_cavs25 - - -Set up the environment -********************** - -1. Copy following two tools to the $HOME directory of the target machine (DUT): - -- soc/xtensa/intel_adsp/tools/cavstool.py - (The firmware loader) - -- soc/xtensa/intel_adsp/tools/remote-fw-service.py - (The remote service provider) - - You can use scp command to copy them to DUT, Ex. - -.. code-block:: console - - $scp boards/xtensa/intel_adsp/tools/cavstool.py user@myboard:~ - $scp boards/xtensa/intel_adsp/tools/remote-fw-service.py user@myboard:~ - -2. In your build machine, install the rimage tool, the signed key and - the toml config file. Please refer to please refer: - - - https://github.com/thesofproject/rimage. - - -How Remote Service works -************************ - -The CAVS remote service runs on the target board and interacts with -west. Two services working on the server: - -- Run Sevice - Run Service (or Request Service) works as a flasher. It will receive and - download the firmware to the intel_adsp_cavs boards then starts the Zephyr - Application. It starts at port 10000 by default. - -- Log Service - Log Service redirect the remote target board's /dev/tty console. It will - output Zephyr's log message to user via network. It starts at port 9999 - by default. - -The --remote-host parameter specify the network address which Run Service -provided, and the --pty parameter specifies the network address of log -output service. - - -Build and run the tests -*********************** - -1. In the remote target machine, starting the service by: - -.. code-block:: console - - sudo ./remote-fw-service.py - -2. Build the application. Take hello world as an example: - -.. code-block:: console - - west build -b intel_adsp_cavs15 samples/hello_world - -3. Run the test by: - -.. code-block:: console - - west flash --remote-host {host}:{port} \ - --pty {host}:{port} - -Ex. - -.. code-block:: console - - west flash --remote-host 192.168.0.1 --pty - - # with specifying the port - west flash --remote-host 192.168.0.1:12345 \ - --pty 192.168.0.1:54321 - - -Now you can see the outout log in your terminal. - - -If you don't want to use the default location of rimage tools, you can -also specify the rimage tool, config and key by: - -.. code-block:: console - - west flash --remote-host {host}:{port} \ - --pty {host}:{port} \ - --rimage-tool [path to the rimage tool] \ - --config-dir [path to dir of .toml config file] \ - --key [path to signing key] - - -The cavstool server will listen to the available network interfaces on -port 9999 and 10000 by default. In some case you might need to specify -it only listen on a dedicate IP address, or change the default ports -using, you can do it with following parameters: - -.. code-block:: console - - # with specifying the port - sudo ./remote-fw-service.py --log-port 54321 --req-port 12345 - - # can be simplified with - sudo ./remote-fw-service -p 54321 -r 12345 - - # with specifying a IP address - sudo ./remote-fw-service -s 192.168.0.2 - - # with specifying the IP address with a log port - sudo ./remote-fw-service -s 192.168.0.2:54321 - - # with specifying the IP, log and request port - sudo ./remote-fw-service -s 192.168.0.2:54321 -r 12345 - - # Also works in this way - sudo ./remote-fw-service -s 192.168.0.2 -p 54321 -r 12345 - - -Run by twister -************** - -For running by twister, the --remote-host parameter needs to be added into -the content of the --west-flash parameter. Assume the IP address of your CAVS -boarad is 192.168.1.2, the port of the Request Service is 12345, the port of -the Log Service is 54321, this is an example of the twister command: - -.. code-block:: console - - twister -p intel_adsp_cavs25 --device-testing \ - --device-serial-pty="$ZEPHYR_BASE/soc/xtensa/intel_adsp/tools/cavstool_client.py,-s,192.168.1.2:54321,-l" \ - --west-flash="--remote-host=192.168.1.4:12345" - - -Like we run tests by west, if you don't want to use the default location of -SOF tools, you can also specify the rimage tool, config and key by: - -.. code-block:: console - - twister -p intel_adsp_cavs15 --device-testing \ - --device-serial-pty="$ZEPHYR_BASE/soc/xtensa/intel_adsp/tools/cavstool_client.py,-s,192.168.1.2:54321,-l" \ - --west-flash="--remote-host=192.168.1.2:12345,\ - --rimage-tool=$HOME/sof/rimage/rimage,\ - --config-dir=$HOME/sof/rimage/config/,\ - --key=$HOME/sof/keys/otc_private_key.pem" \ - -T tests/kernel/semaphore/semaphore/ -vv - - -Note that there should be no space between the arguments in --west-flash, -it use comma to separate the parameters. - - -Run one or multiple boards -************************** - -In the above example, there are many parameters need to be keying in when -running by twister. You can reduce it is by writing a hardware map file. -Ruuning twister with the hardware map file also support you running tests -on single/multiple ADSP boards parallelly. - -Let see how to use a hardware map file by twister to run a single board, -this is the content of the hardware map file cavs.map: - -.. code-block:: console - - - connected: true - id: None - platform: intel_adsp_cavs25 - product: None - runner: intel_adsp - serial_pty: "/home/user/zephyrproject/zephyr/soc/xtensa/intel_adsp/tools/cavstool_client.py,-s,192.168.1.4,-l" - runner_params: - - --remote-host=192.168.1.4 - - -If you need to specify the port using, you can write the hardware map file -like following example. Assume you have a log port of 54321 and a req port -12345: - -.. code-block:: console - - - connected: true - id: None - platform: intel_adsp_cavs25 - product: None - runner: intel_adsp - serial_pty: "/home/user/zephyrproject/zephyr/soc/xtensa/intel_adsp/tools/cavstool_client.py,-s,192.168.1.4,--log-port,54321,-l" - runner_params: - - --remote-host=192.168.1.4 - - --tool-opt=--req-port - - --tool-opt=12345 - - -And another simplified form of the port specifying is to use {host}:{port} -for the --remote-host of the runner params and -s of the serial-pty, Ex. - -.. code-block:: console - - - connected: true - id: None - platform: intel_adsp_cavs25 - product: None - runner: intel_adsp - serial_pty: "/home/user/zephyrproject/zephyr/soc/xtensa/intel_adsp/tools/cavstool_client.py,-s,192.168.1.4:54321,-l" - runner_params: - - --remote-host=192.168.1.4:12345 - - -Then you can run twister with fewer parameters: - -.. code-block:: console - - twister --hardware-map ./cavs.map --device-testing -T samples/hello_world -vv - - -And below example of the hardware map file shows you how to run tests in -mulitple boards: - -.. code-block:: console - - - connected: true - id: None - platform: intel_adsp_cavs15 - product: None - runner: intel_adsp - serial_pty: "/home/user/zephyrproject/zephyr/soc/xtensa/intel_adsp/tools/cavstool_client.py,-s,192.168.1.2,-l" - runner_params: - - --remote-host=192.168.1.2 - - - connected: true - id: None - platform: intel_adsp_cavs18 - product: None - runner: intel_adsp - serial_pty: "/home/user/zephyrproject/zephyr/soc/xtensa/intel_adsp/tools/cavstool_client.py,-s,192.168.1.3,-l" - runner_params: - - --remote-host=192.168.1.3 - - - connected: true - id: None - platform: intel_adsp_cavs25 - product: None - runner: intel_adsp - serial_pty: "/home/user/zephyrproject/zephyr/soc/xtensa/intel_adsp/tools/cavstool_client.py,-s,192.168.1.4,-l" - runner_params: - - --remote-host=192.168.1.4 - -If you don't want to run certain platform in this file, just make -the "connected" field from "true" to "false", it will be skip. - -Again, if you don't use the default location of the SOF tools, you -can remove the --rimage-tool, --config-dir and --key in the extra_params -field. For example: - -.. code-block:: console - - - connected: true - id: None - platform: intel_adsp_cavs25 - product: None - runner: intel_adsp - serial_pty: "/home/user/zephyrproject/zephyr/soc/xtensa/intel_adsp/tools/cavstool_client.py,-s,192.168.1.4,-l" - runner_params: - - --remote-host=192.168.1.4 - - --rimage-tool=/home/user/sof/rimage/rimage - - --config-dir=/home/user/sof/rimage/config/ - - --key=/home/user/sof/keys/otc_private_key_3k.pem - - -To run multiple boards does also work when specifying the ports. - - -Passing extra parameter to tools -******************************** - -wwe can pass parameters to run/require service by the --tool-opt -option. This is for possible extending in the future. For example: - -.. code-block:: console - - west flash --remote-host=192.168.0.1 --pty=192.168.0.1 \ - --tool-opt=--arg='white space' --tool-opt=-r --tool-opt=12345 - -That means our optional parameters will be parsed as: - -.. code-block:: console - - ['--arg=white space', '-r', '12345'] - -Then cavs request service tool can get them. diff --git a/boards/xtensa/intel_adsp_cavs18/doc/index.rst b/boards/xtensa/intel_adsp_cavs18/doc/index.rst new file mode 100644 index 00000000000000..f3f1a0af1665b1 --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs18/doc/index.rst @@ -0,0 +1,34 @@ +.. _intel_adsp_cavs18: + +Intel ADSP CAVS 1.8 +################### + +Overview +******** + +This board configuration is used to run Zephyr on the Intel CAVS 1.8 Audio DSP. +This configuration is present, for example, on Intel `Whiskey Lake`_ microprocessors. +Refer to :ref:`intel_adsp_generic` for more details on Intel ADSP ACE and CAVS. + +System requirements +******************* + +Xtensa Toolchain +---------------- + +If you choose to build with the Xtensa toolchain instead of the Zephyr SDK, set +the following environment variables specific to the board in addition to the +Xtensa toolchain environment variables listed in :ref:`intel_adsp_generic`. + +.. code-block:: shell + + export TOOLCHAIN_VER=RG-2017.8-linux + export XTENSA_CORE=X6H3CNL_2017_8 + +Programming and Debugging +************************* + +Refer to :ref:`intel_adsp_generic` for generic instructions on programming and +debugging applicable to all CAVS and ACE platforms. + +.. _Whiskey Lake: https://www.intel.com/content/www/us/en/products/platforms/details/whiskey-lake.html diff --git a/boards/xtensa/intel_adsp_cavs25/doc/chromebooks_adsp.rst b/boards/xtensa/intel_adsp_cavs25/doc/chromebooks_adsp.rst new file mode 100644 index 00000000000000..95cc5ca32d8847 --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs25/doc/chromebooks_adsp.rst @@ -0,0 +1,417 @@ +:orphan: + +.. _zephyr-audio-dsp-development-on-chromebooks: + +Zephyr Audio DSP Development on Chromebooks +########################################### + +The Audio DSP on Intel Chromebooks is configured to use the SOF +"Community" key for firmware signing, and can therefore accept +arbitrary user-developed firmware like Zephyr applications (of which +SOF is one), including the Zephyr samples and test suite. + +Initial TGL Chromebook Setup +**************************** + +(These instructions were written specifically to the Asus Flip CX5 +device code named "delbin". But they should be reasonably applicable +to any recent Intel device.) + +Power the device on and connect it to a wireless network. It will +likely want to download a firmware update (mine did). Let this finish +first, to ensure you have two working OS images. + +Enable Developer Mode +===================== + +Power the device off (menu in lower right, or hold the power button +on the side) + +Hold Esc + Refresh (the arrow-in-a-circle "reload" key above "3") and +hit the power key to enter recovery mode. Note: the touchscreen and +pad don't work in recovery mode, use the arrow keys to navigate. + +Select "Advanced Options", then "Enable Developer Mode" and confirm +that you really mean it. Select "Boot from Internal Storage" at the +bootloader screen. You will see this screen every time the machine +boots now, telling you that the boot is unverified. + +Wait while the device does the required data wipe. My device takes +about 15 minutes to completely write the stateful partition. On +reboot, select "Boot from Internal Storage" again and set it up +(again) with Google account. + +Make a Recovery Drive +===================== + +You will at some point wreck your device and need a recovery stick. +Install the Chromebook Recovery Utility from the Google Web Store and +make one. + +You can actually do this on any machine (and any OS) with Chrome +installed, but it's easiest on the Chromebook because it knows its +device ID (for example "DELBIN-XHVI D4B-H4D-G4G-Q9A-A9P" for the Asus +Tiger Lake board). Note that recovery, when it happens, will not +affect developer mode or firmware settings but it **will wipe out the +root filesystem and /usr/local customizations you have made**. So +plan on a strategy that can tolerate data loss on the device you're +messing with! + +Make the root filesystem writable +================================= + +For security, ChromeOS signs and cryptographically verifies (using +Linux's dm-verity feature) all access to the read-only root +filesystem. Mucking with the rootfs (for example, to install modules +for a custom kernel) requires that the dm-verity layer be turned off: + +First open a terminal with Ctrl-Alt-T. Then at the "crosh> " prompt +issue the "shell" command to get a shell running as the "chronos" +user. Finally (in developer mode) a simple "sudo su -" will get you a +root prompt. + +.. code-block:: console + + crosh> shell + chronos@localhost / $ sudo su - + localhost ~ # + +Now you need to turn of signature verification in the bootloader +(because obviously we'll be breaking whatever signature existed). +Note that signature verification is something done by the ROM +bootloader, not the OS, and this setting is a (developer-mode-only) +directive to that code: + +.. code-block:: console + + cros# crossystem dev_boot_signed_only=0 + +(*Note: for clarity, commands in this document entered at the ChromeOS +core shell will be prefixed with a hostname of cros.*) + +Next you disable the validation step: + +.. code-block:: console + + cros# /usr/share/vboot/bin/make_dev_ssd.sh --remove_rootfs_verification + +**THIS COMMAND WILL FAIL**, give you an error that you are changing +the setting for the entire running system, and suggest an alternative +"--partitions X" argument to use that modifies only the currently used +partition. Run that modified command, then reboot. + +After rebooting, you will notice that your chromebook boots with the +raw storage device (e.g. /dev/nvme0n1p5) mounted as root and not the +"dm-0" verity device, and that the rootfs is read-write. + +Note: What this command actually does is modify the command line of +the installed kernel image (it saves a backup in +/mnt/stateful_partition/cros_sign_backups) so that it specifies +"root=" and not "root=dm-0". It does seem to leave the other +verity configuration in place though, it just doesn't try to mount the +resulting (now-invalid!) partition. + +Metanote: The astute will note that we're probably going to throw this +kernel out, and that we could probably have just edited the command +line of the new kernel instead of flashing and rebooting into this +modified one. But that's too many balls to juggle at once for me. + +Enable ChromeOS SSH +=================== + +Once you are booted with a writable partition, you can turn on the +built-in ssh server with: + +.. code-block:: console + + cros# /usr/libexec/debugd/helpers/dev_features_ssh + +By default neither the "chronos" user nor root accounts have +passwords, so unless you want to type a ssh key in by hand, you +probably want to set a password for the first login (before you run +ssh-copy-id, of course): + +.. code-block:: console + + cros# passwd + +Now ssh into the chromebook and add your key to +``.ssh/authorized_keys`` as you do for any Linux system. + +Install Crouton +*************** + +The Zephyr integration tools require a proper Linux environment and +won't run on ChromeOS's minimal distro. So we need to install a Linux +personality. **DO NOT** bother installing the "Linux Development +Environment" (Crostini) from the ChromeOS Developer settings. This +personality runs inside a VM, where our tools need access to the real +kernel running on the real hardware. Instead install Crouton +(https://github.com/dnschneid/crouton), which is a community +chroot-based personality that preserves access to the real hardware +sysfs and /dev filesystem. These instructions install the "cli-extra" +package list, there are X11-enabled ones available too if you prefer +to work on the device screen directly. See the project page, etc... + +At a root shell, grab the installer and run it (note: /usr/local is +the only writable filesystem without noexec, you must place the binary +there for it to run!): + +.. code-block:: console + + cros# mkdir -p /usr/local/bin + cros# curl -L https://github.com/dnschneid/crouton/raw/master/installer/crouton \ + > /usr/local/bin/crouton + cros# chmod 755 /usr/local/bin/crouton + cros# crouton -r focal -t cli-extra + +Start the Crouton chroot environment: + +.. code-block:: console + + cros# startcli + +Now you are typing commands into the Ubuntu environment. Enable +inbound ssh on Crouton, but on a port other than 22 (which is used for +the native ChromeOS ssh server). I'm using 222 here (which is easy to +remember, and not a registered port in /etc/services): + +.. code-block:: console + + crouton# apt install iptables openssh-server + crouton# echo "Port 222" >> /etc/ssh/sshd_config + crouton# mkdir /run/sshd + crouton# iptables -I INPUT -p tcp --dport 222 -j ACCEPT + crouton# /usr/sbin/sshd + +(*As above: note that we have introduced a hostname of "crouton" to +refer to the separate Linux personality.*) + +NOTE: the mkdir, iptables and sshd commands need to be run every time +the chroot is restarted. You can put them in /etc/rc.local for +convenience. Crouton doesn't run systemd (because it can't -- it +doesn't own the system!) so Ubuntu services like openssh-server don't +know how to start themselves. + +Building and Installing a Custom Kernel +*************************************** + +On your build host, grab a copy of the ChromeOS kernel tree. The +shipping device is using a 5.4 kernel, but the 5.10 tree works for me +and seems to have been backporting upstream drivers such that its main +hardware is all quite recent (5-6 weeks behind mainline or so). We +place it in the home directory here for simplicity: + +.. code-block:: console + + dev$ cd $HOME + dev$ git clone https://chromium.googlesource.com/chromiumos/third_party/kernel + dev$ cd kernel + dev$ git checkout chromeos-5.10 + +(*Once again, we are typing into a different shell. We introduce the +hostname "dev" here to represent the development machine on which you +are building kernels and Zephyr apps. It is possible to do this on the +chromebook directly, but not advisable. Remember the discussion above +about requiring a drive wipe on system recovery!*) + +Note: you probably have an existing Linux tree somewhere already. If +you do it's much faster to add this as a remote there and just fetch +the deltas -- ChromeOS tracks upstream closely. + +Now you need a .config file. The Chromebook kernel ships with the +"configs" module built which exposes this in the running kernel. You +just have to load the module and read the file. + +.. code-block:: console + + dev$ cd /path/to/kernel + dev$ ssh root@cros modprobe configs + dev$ ssh root@cros zcat /proc/config.gz > .config + +You will need to set some custom configuration variables differently +from ChromeOS defaults (you can edit .config directly, or use +menuconfig, etc...): + ++ ``CONFIG_HUGETLBFS=y`` - The Zephyr loader tool requires this ++ ``CONFIG_EXTRA_FIRMWARE_DIR=n`` - This refers to a build directory + in Google's build environment that we will not have. ++ ``CONFIG_SECURITY_LOADPIN=n`` - Pins modules such that they will + only load from one filesystem. Annoying restriction for custom + kernels. ++ ``CONFIG_MODVERSIONS=n`` - Allow modules to be built and installed + from modified "dirty" build trees. + +Now build your kernel just as you would any other: + +.. code-block:: console + + dev$ make olddefconfig # Or otherwise update .config + dev$ make bzImage modules # Probably want -j for parallel build + +The modules you can copy directly to the (now writable) rootfs on the +device. Note that this filesystem has very limited space (it's +intended to be read only), so the INSTALL_MOD_STRIP=1 is absolutely +required, and you may find you need to regularly prune modules from +older kernels to make space: + +.. code-block:: console + + dev$ make INSTALL_MOD_PATH=mods INSTALL_MOD_STRIP=1 modules_install + dev$ (cd mods/lib/modules; tar cf - .) | ssh root@cros '(cd /lib/modules; tar xfv -)' + +Pack and Install ChromeOS Kernel Image +====================================== + +The kernel bzImage file itself needs to be signed and packaged into a +ChromeOS vboot package and written directly to the kernel partition. +Thankfully the tools to do this are shipped in Debian/Ubuntu +repositories already: + +.. code-block:: console + + $ sudo apt install vboot-utils vboot-kernel-utils + +Find the current kernel partition on the device. You can get this by +comparing the "kernel_guid" command line parameter (passed by the +bootloader) with the partition table of the boot drive, for example: + +.. code-block:: console + + dev$ KPART=`ssh root@cros 'fdisk -l -o UUID,Device /dev/nvme0n1 | \ + grep -i $(sed "s/.*kern_guid=//" /proc/cmdline \ + | sed "s/ .*//") \ + | sed "s/.* //"'` + dev$ echo $KPART + /dev/nvme0n1p4 + +Extract the command line from that image into a local file: + +.. code-block:: console + + dev$ ssh root@cros vbutil_kernel --verify /dev/$KPART | tail -1 > cmdline.txt + +Now you can pack a new kernel image using the vboot tooling. Most of +these arguments are boilerplate and always the same. The keys are +there because the boot requires a valid signature, even though as +configured it won't use it. Note the cannot-actually-be-empty dummy +file passed as a "bootloader", which is a holdover from previous ROM +variants which needed an EFI stub. + +.. code-block:: console + + dev$ echo dummy > dummy.efi + dev$ vbutil_kernel --pack kernel.img --config cmdline.txt \ + --vmlinuz arch/x86_64/boot/bzImage \ + --keyblock /usr/share/vboot/devkeys/kernel.keyblock \ + --signprivate /usr/share/vboot/devkeys/kernel_data_key.vbprivk \ + --version 1 --bootloader dummy.efi --arch x86_64 + +You can verify this image if you like with "vbutil_kernel --verify". + +Now just copy up the file and write it to the partition on the device: + +.. code-block:: console + + $ scp kernel.img root@cros:/tmp + $ ssh root@cros dd if=/tmp/kernel.img of=/dev/nvme0n1p4 + +Now reboot, and if all goes well you will find yourself running in +your new kernel. + +Wifi Firmware Fixup +=================== + +On the Tiger Lake Chromebook, the /lib/firmware tree is a bit stale +relative to the current 5.10 kernel. The iwlwifi driver requests a +firmware file that doesn't exist, leading to a device with no network. +It's a simple problem, but a catastrophic drawback if uncorrected. It +seems to be sufficient just to link the older version to the new name. +(It would probably be better to copy the proper version from +/lib/firmware from a recent kernel.org checkout.): + +.. code-block:: console + + cros# cd /lib/firmware + cros# ln -s iwlwifi-QuZ-a0-hr-b0-62.ucode iwlwifi-QuZ-a0-hr-b0-64.ucode + +Build and Run a Zephyr Application +********************************** + +Finally, with your new kernel booted, you are ready to run Zephyr +code. + +Build rimage Signing Tool +========================= + +First download and build a copy of the Sound Open Firmware "rimage" +tool (these instructions put it in your home directory for clarity, +but anywhere is acceptable): + +.. code-block:: console + + dev$ cd $HOME + dev$ git clone https://github.com/thesofproject/rimage + dev$ cd rimage/ + dev$ git submodule init + dev$ git submodule update + dev$ cmake . + dev$ make + +Copy Integration Scripting to Chromebook +======================================== + +There is a python scripts needed on the device, to be run inside +the Crouton environment installed above. Copy them: + +.. code-block:: console + + dev$ scp boards/xtensa/intel_adsp_cavs15/tools/cavstool.py user@crouton: + +Then start the service in the Crouton environment: + +.. code-block:: console + + crouton$ sudo ./cavstool.py user@crouton: + + +Build and Sign Zephyr App +========================= + +Zephyr applications build conventionally for this platform, and are +signed with "west flash" with just a few extra arguments. Note that +the key in use for the Tiger Lake DSP is the "3k" key from SOF, not +the original that is used with older hardware. The output artifact is +a "zephyr.ri" file to be copied to the device. + +.. code-block:: console + + dev$ west build -b intel_adsp_cavs25 samples/hello_world + dev$ west sign --tool-data=~/rimage/config -t ~/rimage/rimage -- \ + -k $ZEPHYR_BASE/../modules/audio/sof/keys/otc_private_key_3k.pem + +Run it! +======= + +The loader script takes the signed rimage file as its argument. Once +it reports success, the application begins running immediately and its +console output (in the SOF shared memory trace buffer) can be read by +the logging script. + +.. code-block:: console + + dev$ west flash --remote-host crouton + Hello World! intel_adsp_cavs25 + +Misc References +*************** + +Upstream documentation from which these instructions were drawn: + +This page has the best reference for the boot process: + +http://www.chromium.org/chromium-os/chromiumos-design-docs/disk-format + +This is great too, with an eye toward booting things other than ChromeOS: + +https://www.chromium.org/chromium-os/developer-information-for-chrome-os-devices/custom-firmware diff --git a/boards/xtensa/intel_adsp_cavs25/doc/index.rst b/boards/xtensa/intel_adsp_cavs25/doc/index.rst index 31a121054bb0ac..437560562e0989 100644 --- a/boards/xtensa/intel_adsp_cavs25/doc/index.rst +++ b/boards/xtensa/intel_adsp_cavs25/doc/index.rst @@ -1,415 +1,34 @@ -.. _zephyr-audio-dsp-development-on-chromebooks: +.. _intel_adsp_cavs25: -Zephyr Audio DSP Development on Chromebooks -########################################### +Intel ADSP CAVS 2.5 +################### -The Audio DSP on Intel Chromebooks is configured to use the SOF -"Community" key for firmware signing, and can therefore accept -arbitrary user-developed firmware like Zephyr applications (of which -SOF is one), including the Zephyr samples and test suite. +Overview +******** -Initial TGL Chromebook Setup -**************************** +This board configuration is used to run Zephyr on the Intel CAVS 2.5 Audio DSP. +This configuration is present, for example, on Intel `Tiger Lake`_ microprocessors. +Refer to :ref:`intel_adsp_generic` for more details on Intel ADSP ACE and CAVS. -(These instructions were written specifically to the Asus Flip CX5 -device code named "delbin". But they should be reasonably applicable -to any recent Intel device.) +System requirements +******************* -Power the device on and connect it to a wireless network. It will -likely want to download a firmware update (mine did). Let this finish -first, to ensure you have two working OS images. +Xtensa Toolchain +---------------- -Enable Developer Mode -===================== +If you choose to build with the Xtensa toolchain instead of the Zephyr SDK, set +the following environment variables specific to the board in addition to the +Xtensa toolchain environment variables listed in :ref:`intel_adsp_generic`. -Power the device off (menu in lower right, or hold the power button -on the side) +.. code-block:: shell -Hold Esc + Refresh (the arrow-in-a-circle "reload" key above "3") and -hit the power key to enter recovery mode. Note: the touchscreen and -pad don't work in recovery mode, use the arrow keys to navigate. + export TOOLCHAIN_VER=RG-2017.8-linux + export XTENSA_CORE=cavs2x_LX6HiFi3_2017_8 -Select "Advanced Options", then "Enable Developer Mode" and confirm -that you really mean it. Select "Boot from Internal Storage" at the -bootloader screen. You will see this screen every time the machine -boots now, telling you that the boot is unverified. +Programming and Debugging +************************* -Wait while the device does the required data wipe. My device takes -about 15 minutes to completely write the stateful partition. On -reboot, select "Boot from Internal Storage" again and set it up -(again) with Google account. +Refer to :ref:`intel_adsp_generic` for generic instructions on programming and +debugging applicable to all CAVS and ACE platforms. -Make a Recovery Drive -===================== - -You will at some point wreck your device and need a recovery stick. -Install the Chromebook Recovery Utility from the Google Web Store and -make one. - -You can actually do this on any machine (and any OS) with Chrome -installed, but it's easiest on the Chromebook because it knows its -device ID (for example "DELBIN-XHVI D4B-H4D-G4G-Q9A-A9P" for the Asus -Tiger Lake board). Note that recovery, when it happens, will not -affect developer mode or firmware settings but it **will wipe out the -root filesystem and /usr/local customizations you have made**. So -plan on a strategy that can tolerate data loss on the device you're -messing with! - -Make the root filesystem writable -================================= - -For security, ChromeOS signs and cryptographically verifies (using -Linux's dm-verity feature) all access to the read-only root -filesystem. Mucking with the rootfs (for example, to install modules -for a custom kernel) requires that the dm-verity layer be turned off: - -First open a terminal with Ctrl-Alt-T. Then at the "crosh> " prompt -issue the "shell" command to get a shell running as the "chronos" -user. Finally (in developer mode) a simple "sudo su -" will get you a -root prompt. - -.. code-block:: console - - crosh> shell - chronos@localhost / $ sudo su - - localhost ~ # - -Now you need to turn of signature verification in the bootloader -(because obviously we'll be breaking whatever signature existed). -Note that signature verification is something done by the ROM -bootloader, not the OS, and this setting is a (developer-mode-only) -directive to that code: - -.. code-block:: console - - cros# crossystem dev_boot_signed_only=0 - -(*Note: for clarity, commands in this document entered at the ChromeOS -core shell will be prefixed with a hostname of cros.*) - -Next you disable the validation step: - -.. code-block:: console - - cros# /usr/share/vboot/bin/make_dev_ssd.sh --remove_rootfs_verification - -**THIS COMMAND WILL FAIL**, give you an error that you are changing -the setting for the entire running system, and suggest an alternative -"--partitions X" argument to use that modifies only the currently used -partition. Run that modified command, then reboot. - -After rebooting, you will notice that your chromebook boots with the -raw storage device (e.g. /dev/nvme0n1p5) mounted as root and not the -"dm-0" verity device, and that the rootfs is read-write. - -Note: What this command actually does is modify the command line of -the installed kernel image (it saves a backup in -/mnt/stateful_partition/cros_sign_backups) so that it specifies -"root=" and not "root=dm-0". It does seem to leave the other -verity configuration in place though, it just doesn't try to mount the -resulting (now-invalid!) partition. - -Metanote: The astute will note that we're probably going to throw this -kernel out, and that we could probably have just edited the command -line of the new kernel instead of flashing and rebooting into this -modified one. But that's too many balls to juggle at once for me. - -Enable ChromeOS SSH -=================== - -Once you are booted with a writable partition, you can turn on the -built-in ssh server with: - -.. code-block:: console - - cros# /usr/libexec/debugd/helpers/dev_features_ssh - -By default neither the "chronos" user nor root accounts have -passwords, so unless you want to type a ssh key in by hand, you -probably want to set a password for the first login (before you run -ssh-copy-id, of course): - -.. code-block:: console - - cros# passwd - -Now ssh into the chromebook and add your key to -``.ssh/authorized_keys`` as you do for any Linux system. - -Install Crouton -*************** - -The Zephyr integration tools require a proper Linux environment and -won't run on ChromeOS's minimal distro. So we need to install a Linux -personality. **DO NOT** bother installing the "Linux Development -Environment" (Crostini) from the ChromeOS Developer settings. This -personality runs inside a VM, where our tools need access to the real -kernel running on the real hardware. Instead install Crouton -(https://github.com/dnschneid/crouton), which is a community -chroot-based personality that preserves access to the real hardware -sysfs and /dev filesystem. These instructions install the "cli-extra" -package list, there are X11-enabled ones available too if you prefer -to work on the device screen directly. See the project page, etc... - -At a root shell, grab the installer and run it (note: /usr/local is -the only writable filesystem without noexec, you must place the binary -there for it to run!): - -.. code-block:: console - - cros# mkdir -p /usr/local/bin - cros# curl -L https://github.com/dnschneid/crouton/raw/master/installer/crouton \ - > /usr/local/bin/crouton - cros# chmod 755 /usr/local/bin/crouton - cros# crouton -r focal -t cli-extra - -Start the Crouton chroot environment: - -.. code-block:: console - - cros# startcli - -Now you are typing commands into the Ubuntu environment. Enable -inbound ssh on Crouton, but on a port other than 22 (which is used for -the native ChromeOS ssh server). I'm using 222 here (which is easy to -remember, and not a registered port in /etc/services): - -.. code-block:: console - - crouton# apt install iptables openssh-server - crouton# echo "Port 222" >> /etc/ssh/sshd_config - crouton# mkdir /run/sshd - crouton# iptables -I INPUT -p tcp --dport 222 -j ACCEPT - crouton# /usr/sbin/sshd - -(*As above: note that we have introduced a hostname of "crouton" to -refer to the separate Linux personality.*) - -NOTE: the mkdir, iptables and sshd commands need to be run every time -the chroot is restarted. You can put them in /etc/rc.local for -convenience. Crouton doesn't run systemd (because it can't -- it -doesn't own the system!) so Ubuntu services like openssh-server don't -know how to start themselves. - -Building and Installing a Custom Kernel -*************************************** - -On your build host, grab a copy of the ChromeOS kernel tree. The -shipping device is using a 5.4 kernel, but the 5.10 tree works for me -and seems to have been backporting upstream drivers such that its main -hardware is all quite recent (5-6 weeks behind mainline or so). We -place it in the home directory here for simplicity: - -.. code-block:: console - - dev$ cd $HOME - dev$ git clone https://chromium.googlesource.com/chromiumos/third_party/kernel - dev$ cd kernel - dev$ git checkout chromeos-5.10 - -(*Once again, we are typing into a different shell. We introduce the -hostname "dev" here to represent the development machine on which you -are building kernels and Zephyr apps. It is possible to do this on the -chromebook directly, but not advisable. Remember the discussion above -about requiring a drive wipe on system recovery!*) - -Note: you probably have an existing Linux tree somewhere already. If -you do it's much faster to add this as a remote there and just fetch -the deltas -- ChromeOS tracks upstream closely. - -Now you need a .config file. The Chromebook kernel ships with the -"configs" module built which exposes this in the running kernel. You -just have to load the module and read the file. - -.. code-block:: console - - dev$ cd /path/to/kernel - dev$ ssh root@cros modprobe configs - dev$ ssh root@cros zcat /proc/config.gz > .config - -You will need to set some custom configuration variables differently -from ChromeOS defaults (you can edit .config directly, or use -menuconfig, etc...): - -+ ``CONFIG_HUGETLBFS=y`` - The Zephyr loader tool requires this -+ ``CONFIG_EXTRA_FIRMWARE_DIR=n`` - This refers to a build directory - in Google's build environment that we will not have. -+ ``CONFIG_SECURITY_LOADPIN=n`` - Pins modules such that they will - only load from one filesystem. Annoying restriction for custom - kernels. -+ ``CONFIG_MODVERSIONS=n`` - Allow modules to be built and installed - from modified "dirty" build trees. - -Now build your kernel just as you would any other: - -.. code-block:: console - - dev$ make olddefconfig # Or otherwise update .config - dev$ make bzImage modules # Probably want -j for parallel build - -The modules you can copy directly to the (now writable) rootfs on the -device. Note that this filesystem has very limited space (it's -intended to be read only), so the INSTALL_MOD_STRIP=1 is absolutely -required, and you may find you need to regularly prune modules from -older kernels to make space: - -.. code-block:: console - - dev$ make INSTALL_MOD_PATH=mods INSTALL_MOD_STRIP=1 modules_install - dev$ (cd mods/lib/modules; tar cf - .) | ssh root@cros '(cd /lib/modules; tar xfv -)' - -Pack and Install ChromeOS Kernel Image -====================================== - -The kernel bzImage file itself needs to be signed and packaged into a -ChromeOS vboot package and written directly to the kernel partition. -Thankfully the tools to do this are shipped in Debian/Ubuntu -repositories already: - -.. code-block:: console - - $ sudo apt install vboot-utils vboot-kernel-utils - -Find the current kernel partition on the device. You can get this by -comparing the "kernel_guid" command line parameter (passed by the -bootloader) with the partition table of the boot drive, for example: - -.. code-block:: console - - dev$ KPART=`ssh root@cros 'fdisk -l -o UUID,Device /dev/nvme0n1 | \ - grep -i $(sed "s/.*kern_guid=//" /proc/cmdline \ - | sed "s/ .*//") \ - | sed "s/.* //"'` - dev$ echo $KPART - /dev/nvme0n1p4 - -Extract the command line from that image into a local file: - -.. code-block:: console - - dev$ ssh root@cros vbutil_kernel --verify /dev/$KPART | tail -1 > cmdline.txt - -Now you can pack a new kernel image using the vboot tooling. Most of -these arguments are boilerplate and always the same. The keys are -there because the boot requires a valid signature, even though as -configured it won't use it. Note the cannot-actually-be-empty dummy -file passed as a "bootloader", which is a holdover from previous ROM -variants which needed an EFI stub. - -.. code-block:: console - - dev$ echo dummy > dummy.efi - dev$ vbutil_kernel --pack kernel.img --config cmdline.txt \ - --vmlinuz arch/x86_64/boot/bzImage \ - --keyblock /usr/share/vboot/devkeys/kernel.keyblock \ - --signprivate /usr/share/vboot/devkeys/kernel_data_key.vbprivk \ - --version 1 --bootloader dummy.efi --arch x86_64 - -You can verify this image if you like with "vbutil_kernel --verify". - -Now just copy up the file and write it to the partition on the device: - -.. code-block:: console - - $ scp kernel.img root@cros:/tmp - $ ssh root@cros dd if=/tmp/kernel.img of=/dev/nvme0n1p4 - -Now reboot, and if all goes well you will find yourself running in -your new kernel. - -Wifi Firmware Fixup -=================== - -On the Tiger Lake Chromebook, the /lib/firmware tree is a bit stale -relative to the current 5.10 kernel. The iwlwifi driver requests a -firmware file that doesn't exist, leading to a device with no network. -It's a simple problem, but a catastrophic drawback if uncorrected. It -seems to be sufficient just to link the older version to the new name. -(It would probably be better to copy the proper version from -/lib/firmware from a recent kernel.org checkout.): - -.. code-block:: console - - cros# cd /lib/firmware - cros# ln -s iwlwifi-QuZ-a0-hr-b0-62.ucode iwlwifi-QuZ-a0-hr-b0-64.ucode - -Build and Run a Zephyr Application -********************************** - -Finally, with your new kernel booted, you are ready to run Zephyr -code. - -Build rimage Signing Tool -========================= - -First download and build a copy of the Sound Open Firmware "rimage" -tool (these instructions put it in your home directory for clarity, -but anywhere is acceptable): - -.. code-block:: console - - dev$ cd $HOME - dev$ git clone https://github.com/thesofproject/rimage - dev$ cd rimage/ - dev$ git submodule init - dev$ git submodule update - dev$ cmake . - dev$ make - -Copy Integration Scripting to Chromebook -======================================== - -There is a python scripts needed on the device, to be run inside -the Crouton environment installed above. Copy them: - -.. code-block:: console - - dev$ scp boards/xtensa/intel_adsp_cavs15/tools/cavstool.py user@crouton: - -Then start the service in the Crouton environment: - -.. code-block:: console - - crouton$ sudo ./cavstool.py user@crouton: - - -Build and Sign Zephyr App -========================= - -Zephyr applications build conventionally for this platform, and are -signed with "west flash" with just a few extra arguments. Note that -the key in use for the Tiger Lake DSP is the "3k" key from SOF, not -the original that is used with older hardware. The output artifact is -a "zephyr.ri" file to be copied to the device. - -.. code-block:: console - - dev$ west build -b intel_adsp_cavs25 samples/hello_world - dev$ west sign --tool-data=~/rimage/config -t ~/rimage/rimage -- \ - -k $ZEPHYR_BASE/../modules/audio/sof/keys/otc_private_key_3k.pem - -Run it! -======= - -The loader script takes the signed rimage file as its argument. Once -it reports success, the application begins running immediately and its -console output (in the SOF shared memory trace buffer) can be read by -the logging script. - -.. code-block:: console - - dev$ west flash --remote-host crouton - Hello World! intel_adsp_cavs25 - -Misc References -*************** - -Upstream documentation from which these instructions were drawn: - -This page has the best reference for the boot process: - -http://www.chromium.org/chromium-os/chromiumos-design-docs/disk-format - -This is great too, with an eye toward booting things other than ChromeOS: - -https://www.chromium.org/chromium-os/developer-information-for-chrome-os-devices/custom-firmware +.. _Tiger Lake: https://www.intel.com/content/www/us/en/products/platforms/details/tiger-lake-h.html diff --git a/boards/xtensa/intel_adsp_cavs25/doc/intel_adsp_generic.rst b/boards/xtensa/intel_adsp_cavs25/doc/intel_adsp_generic.rst new file mode 100644 index 00000000000000..50850574ae146a --- /dev/null +++ b/boards/xtensa/intel_adsp_cavs25/doc/intel_adsp_generic.rst @@ -0,0 +1,340 @@ +:orphan: + +.. _intel_adsp_generic: + +Intel ADSP CAVS and ACE +####################### + +Intel's Audio and Digital Signal Processing (ADSP) hardware offerings +include the Converged Audio Video Sensing (CAVS) series and its successor, +the Audio and Context Engine (ACE). These Xtensa-based ADSPs can be integrated +into a variety of Intel products. The below table lists (some of) the Intel +microprocessor(s) that each version of the Intel ADSP is compatible with. + ++----------+-----------------------------+ +| ADSP | Microprocessor | ++==========+=============================+ +| CAVS 1.5 | Apollo Lake | ++----------+-----------------------------+ +| CAVS 1.8 | Whiskey Lake | ++----------+-----------------------------+ +| CAVS 2.5 | Tiger Lake | ++----------+-----------------------------+ +| ACE 1.5 | Meteor Lake | ++----------+-----------------------------+ + +Intel open-sources firmware for its ADSP hardware under the Sound Open Firmware +(`SOF`_) project. SOF can be built with either Zephyr or Cadence's proprietary +Xtensa OS (XTOS) and run on a variety of Intel and non-Intel platforms. + +In general, the Intel `UP2`_ and `UP Xtreme`_ product lines are the publicly +available reference boards for Zephyr's Intel ADSP support. This guide uses the +`UP Xtreme i11-0001 series`_ (:ref:`intel_adsp_cavs25`) board as an example. +However, the instructions are generic and will work on other boards unless +otherwise stated. You will be referred to the documentation for your specific +board in these cases. + +System requirements +******************* + +Setting Up Target Board +----------------------- + +You can only flash Zephyr to the ADSP by using Zephyr's Python tool in a Linux +host running on the board's main CPU. It is possible (and recommended) for users +to build the binary locally on their development machine and flash remotely, +but the board itself must be capable of running the Python script that receives +the binary sent over the network by West and flashes it. You should install a +version of Linux that supports or comes with the current version of Python that +Zephyr requires. Consider using Ubuntu 20.04, which comes with Python 3.8 +installed. + +Note that if you plan to use SOF on your board, you will need to build and +install the modified Linux SOF kernel instead of the default kernel. It is +recommended you follow the `SOF instructions`_ to build and run SOF on Zephyr. + +UP2 and UP Xtreme users can refer to the `UP Community wiki`_ for help installing a +Linux operating system on their board. + +Signing Tool +------------ + +As firmware binary signing is mandatory on Intel products from Skylake onwards, +you will also need to set up the SOF rimage signing tool and key. + +.. code-block:: shell + + cd zephyrproject/modules/audio/sof/ + git clone https://github.com/thesofproject/rimage --recurse-submodules + cd rimage + +Follow the instructions in the :file:`README.md` to build and install the tool +globally on your system. You should be able to invoke the binary from the +command line with the name "rimage". For example: + +.. code-block:: shell + + which rimage + /usr/local/bin/rimage + +If you are unable to install it, you can also pass the path to the tool binary +as an argument to ``west flash``, though this is not recommended. + +Xtensa Toolchain (Optional) +--------------------------- + +The Zephyr SDK provides GCC-based toolchains necessary to build Zephyr for +the CAVS and ACE boards. However, users seeking greater levels of optimization +may desire to build with the proprietary Xtensa toolchain distributed by +`Cadence`_ instead. The following instructions assume you have purchased and +installed the toolchain(s) and core(s) for your board following their +instructions. + +First, make sure to set ``XTENSAD_LICENSE_FILE`` as instructed by Cadence. +Next, set the following environment variables: + +.. code-block:: shell + + export XTENSA_TOOLCHAIN_PATH=$HOME/xtensa/XtDevTools/install/tools + export XTENSA_BUILDS_DIR=$XTENSA_TOOLCHAIN_PATH/../builds + export ZEPHYR_TOOLCHAIN_VARIANT=xcc + export TOOLCHAIN_VER=RG-2017.8-linux + export XTENSA_CORE=cavs2x_LX6HiFi3_2017_8 + +The bottom three variables are specific to each version of CAVS / ACE; refer to +your board's documentation for their values. + +Programming and Debugging +************************* + +Building +-------- + +Build as usual. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: intel_adsp_cavs25 + :goals: build + +Signing +------- + +West automatically signs the binary as the first step of flashing, but if you +need to sign the binary yourself without flashing, you can invoke the west sign +command directly. Read the output of a ``west flash`` command to find the +``west sign`` invocation. You can copy and modify it for your own purposes. + +As mentioned previously, if you're unable to install the rimage tool +globally, you can pass it the path to the tool binary as an argument to +``west flash`` if the flash target exists for your board. To see a list +of all arguments to the Intel ADSP runner, run the following after you have +built the binary. There are multiple arguments related to signing, including a +key argument. + +.. code-block:: console + + west flash --context + +Remote Flashing to CAVS-based ADSP +---------------------------------- + +As mentioned previously, the recommended way to run and monitor the output of +Zephyr on CAVS boards is remotely. The Linux host on the main CPU may freeze up +and need to be restarted if a flash or runtime error occurs on the ADSP. From +this point onward, we will refer to the board as the "remote host" and your +development machine as the "local host". + +Copy the below scripts to the CAVS board. +:zephyr_file:`soc/xtensa/intel_adsp/tools/remote-fw-service.py` will receive +the binary sent over the network by West and invoke +:zephyr_file:`soc/xtensa/intel_adsp/tools/cavstool.py` (referred to as the +"CAVS tool"), which performs the flash and captures the log. Start +:file:`remote-fw-service.py`. + +.. code-block:: console + + scp -r $ZEPHYR_BASE/soc/xtensa/intel_adsp/tools/cavstool.py username@remotehostname + scp -r $ZEPHYR_BASE/soc/xtensa/intel_adsp/tools/remote-fw-service.py username@remotehostname + ssh username@remotehostname + sudo ./remote-fw-service.py + +:file:`remote-fw-service.py` uses ports 9999 and 10000 on the remote host to +communicate. It forwards logs collected by :file:`cavstool.py` on port 9999 +(referred to as its "log port") and services requests on port 10000 +(its "requests port"). When you run West or Twister on your local host, +it sends requests using the :zephyr_file:`soc/xtensa/intel_adsp/tools/cavstool_client.py` +script (referred to as "CAVS tool client"). It also uses ports 9999 and 10000 on +your local host, so be sure those ports are free. + +Flashing with West is simple. + +.. code-block:: console + + west flash --remote-host remotehostname --pty remotehostname + +Running tests with Twister is slightly more complicated. + +.. code-block:: console + + twister -p intel_adsp_cavs25 --device-testing --device-serial-pty="$ZEPHYR_BASE/soc/xtensa/intel_adsp/tools/cavstool_client.py,-s,remotehostname,-l" --west-flash="--remote-host=remotehostname" -T samples/hello_world + +If your network is set up such that the TCP connection from +:file:`cavstool_client.py` to :file:`remote-fw-service.py` is forwarded through +an intermediate host, you may need to tell :file:`cavstool_client.py` to connect +to different ports as well as a different hostname. You can do this by appending +the port numbers to the intermediate host name. + +.. code-block:: console + + west flash --remote-host intermediatehost:reqport --pty remotehostname:logport + twister -p intel_adsp_cavs25 --device-testing --device-serial-pty="$ZEPHYR_BASE/soc/xtensa/intel_adsp/tools/cavstool_client.py,-s,remotehostname:logport,-l" --west-flash="--remote-host=remotehostname:reqport" -T samples/hello_world + +You can also save this information to a hardware map file and pass that to +Twister. + +.. code-block:: console + + twister -p intel_adsp_cavs25 --hardware-map cavs.map --device-testing -T samples/hello_world + +Here's a sample ``cavs.map``: + +.. code-block:: console + + - connected: true + id: None + platform: intel_adsp_cavs25 + product: None + runner: intel_adsp + serial_pty: "/home/zephyrus/zephyrproject/zephyr/soc/xtensa/intel_adsp/tools/cavstool_client.py,-s,remotehostname:logport,-l" + runner_params: + - --remote-host=remotehostname:reqport + +Any of the arguments you would pass to Twister or West, you can pass with the +hardware map. As mentioned previously, you can see the Intel ADSP runner +arguments by passing the ``--context`` flag while flashing with West. + +Refer to :ref:`twister_script` for more information on hardware maps. + +Local Flashing to CAVS-based ADSP +--------------------------------- + +You can also directly flash the signed binary with the CAVS tool on the board. +This may be useful for debugging. + +.. code-block:: console + + sudo ./cavstool.py zephyr.ri + +You should see the following at the end of the log if you are successful: + +.. code-block:: console + + ***** Booting Zephyr OS vx.x.x-xxx-gxxxxxxxxxxxx ***** + Hello World! intel_adsp_cavs25 + +Flashing to ACE-based ADSP +-------------------------- + +Flashing is not yet supported for platforms with ACE-based ADSP, as these +platforms are not yet publicly available. + +Debugging +--------- + +As Zephyr doesn't (yet) support GDB for the Intel ADSP platforms, users are +recommended to take advantage of Zephyr's built-in :ref:`coredump` and +:ref:`logging_api` features. + +Troubleshooting +*************** + +You can pass verbose flags directly to the Intel ADSP scripts: + +.. code-block:: console + + sudo ./remote-fw-service.py -v + sudo ./cavstool.py zephyr.ri -v + +To see a list of their arguments: + +.. code-block:: console + + sudo ./remote-fw-service.py --help + sudo ./cavstool.py --help + +If flashing fails at ``west sign`` with errors related to unparsed keys, try +reinstalling the latest version of the signing tool. For example: + +.. code-block:: shell + + error: 1 unparsed keys left in 'adsp' + error: 1 unparsed arrays left in 'adsp' + +If you get an "Address already in use" error when starting +:file:`remote-fw-service.py` on the board, you may have another instance of the +script running. Kill it. + +.. code-block:: console + + $ sudo netstat -peanut | grep 9999 + tcp 0 0 0.0.0.0:9999 0.0.0.0:* LISTEN 0 289788 14795/python3 + $ sudo kill 14795 + +If West or Twister successfully sign and establish TCP connections +with :file:`remote-fw-service.py` but hang with no output afterwards, +there are two possibilities: either :file:`remote-fw-service.py` failed +to communicate, or :file:`cavstool.py` failed to flash. Log into +the remote host and check the output of :file:`remote-fw-service.py`. + +If a message about "incorrect communication" appears, you mixed up the port +numbers for logging and requests in your command or hardware map. Switch them +and try again. + +.. code-block:: shell + + ERROR:remote-fw:incorrect monitor communication! + +If a "load failed" message appears, that means the flash failed. Examine the +log of ``west flash`` and carefully check that the arguments to ``west sign`` +are correct. + +.. code-block:: console + + WARNING:cavs-fw:Load failed? FW_STATUS = 0x81000012 + INFO:cavs-fw:cAVS firmware load complete + -- + +Sometimes a flash failure or network miscommunication corrupts the state of +the ADSP or :file:`remote-fw-service.py`. If you are unable to identify a +cause of repeated failures, try restarting the scripts and / or power cycling +your board to reset the state. + +Users - particularly, users of the Xtensa toolchain - should also consider +clearing their Zephyr cache, as caching issues can occur from time to time. +Delete the cache as well as any applicable build directories and start from +scratch. You can try using the "pristine" option of West first, if you like. + +.. code-block:: console + + rm -rf build twister-out* + rm -rf ~/.ccache ~/.cache/zephyr + +Xtensa toolchain users can get more detailed logs from the license server by +exporting ``FLEXLM_DIAGNOSTICS=3``. + +.. _SOF: https://thesofproject.github.io/latest/index.html + +.. _Chromebooks: https://www.hp.com/us-en/shop/pdp/hp-chromebook-x360-14c-cc0047nr + +.. _UP2: https://up-board.org/upsquared/specifications/ + +.. _UP Xtreme: https://up-board.org/up-xtreme/ + +.. _UP Xtreme i11-0001 series: https://up-shop.org/up-xtreme-i11-boards-0001-series.html + +.. _SOF instructions: https://thesofproject.github.io/latest/getting_started/build-guide/build-with-zephyr.html + +.. _UP Community wiki: https://github.com/up-board/up-community/wiki/Ubuntu + +.. _Cadence: https://www.cadence.com/en_US/home/tools/ip/tensilica-ip.html