======================= Cortex®-M33 development ======================= Coprocessor Firmware Development ================================ STM provides the STM32MP2 Developer Package to develop on Arm® Cortex®-M33 side. Starting up with development on Arm® Cortex®-M33 read the STM documentation: `Develop on Arm® Cortex®-M33 `_. STM32MP2 boot flavor ==================== The STM32MP2 Cortex-M33 boot mode is configured via BOOT pins. , allowing it to act as the primary boot processor (Trusted Domain) from sources like SD-Card/eMMC, or to be started later by the Cortex-A35 (e.g., via Linux/remoteproc), depending on the chosen boot flavor and pin settings. Differences Between A35-TD Flavor and M33-TD Flavor Boot Chains --------------------------------------------------------------- STM32MP2 supports two possible Trusted Domain (TD) configurations, defining which processor acts as the first trusted core after the ROM code. These configurations affect how the secure boot chain progresses and where trust anchors are placed. .. admonition:: important :class: important The actual BSP supports only the A35-TD Flavor Boot Chain at the moment. A35-TD Flavor Boot Chain ^^^^^^^^^^^^^^^^^^^^^^^^ Cortex-A35 is booting first. Cortex-M33 is kept under reset by hardware until application request to start it. The Trusted Domain continues on the CA35. After the immutable ROM boot (in the Manufacturer Trusted Domain), the secure boot chain flows directly toward the Cortex-A35. **Boot Sequence:** 1) ROM Code + Authenticates and loads next stage, Trusted Firmware-A (TF-A) used as the FSBL 2) Trusted early boot on CA35 + In TF-A BL31 - CA35 enters secure mode (EL3) + Loads secure monitor, trusted firmware, security services 3) CA35 launches non-secure OS (Linux) **Result:** + CA35 is the anchor for the Owner Trusted Domain + Secure services executed by the A35 secure monitor (OP-TEE) + CM33 is brought up after CA35 and typically runs non-trusted firmware unless OEM places additional constraints. M33-TD Flavor Boot Chain ^^^^^^^^^^^^^^^^^^^^^^^^ The Trusted Domain continues on the CM33. This configuration gives the CM33 ownership of early secure boot and secure services. **Boot Sequence:** 1) ROM Code + Authenticates first CM33 firmware image 2) CM33 secure boot execution + CM33 runs the trusted firmware stack + CM33 configures security boundaries (firewalls, SAU/IDAU, memory splits) + CM33 may host a TEE-like secure environment 3) CM33 releases CA35 + CA35 boots into Linux or other OS in non-secure domain **Result:** + CM33 is the anchor of the Owner Trusted Domain + CM33 controls access to security-critical peripherals + CA35 is always subordinate to CM33’s security configuration How to prepare your Linux image for Cortex®-M33 Coprocessor support =================================================================== To support the Cortex®-M33 coprocessor, a number of kernel features must be installed that are not available in the standard image. This is accomplished in Yocto by using a special distro feature. To add this Distro Feature, open your local.conf and add the following line: .. code-block:: text DISTRO_FEATURES:append = " copro" How to install the FDT overlay for Coprocessor support ====================================================== Additional device tree features must be integrated via a special device tree overlay for the coprozessor. For more information about FDT overlays, please see :ref:`FDT Overlays` To install the overlay, a baseboard variable must be set in the U-Boot environment, and the overlay name must be added to the appropriate ``overlays_${baseboard}`` variable, e.g.: .. code-block:: text setenv baseboard setenv overlays_ ${overlays_} karo-copro saveenv Deploying the firmware to the target ==================================== To start the firmware, we have to deploy it first to the target's memory. That could be basicly, the internal emmc device of the SOM or the SD-card of the base board. The following example shows, how to deploy the firmware to the internal emmc device. After building the yocto Linux and programming it with the uuu-tool to the target, we can examine the programmed partitions inside U-Boot: .. prompt:: :prompts: U-Boot> part list mmc 0 .. code-block:: text Partition Map for MMC device 0 -- Partition Type: EFI Part Start LBA End LBA Name Attributes Type GUID Partition GUID 1 0x00000800 0x000017ff "fip" attrs: 0x0000000000000000 type: 19d5df83-11b0-457b-be2c-7559c13142a5 (19d5df83-11b0-457b-be2c-7559c13142a5) guid: aff42d55-134f-449c-b892-92bf1a6f7955 2 0x00001800 0x000217ff "boot" attrs: 0x0000000000000000 type: bc13c2ff-59e6-4262-a352-b275fd6f7172 (bc13c2ff-59e6-4262-a352-b275fd6f7172) guid: 36d1f7ae-9e50-46ce-accf-57989189f556 3 0x00021800 0x000617ff "rootfs" attrs: 0x0000000000000000 type: b921b045-1df0-41c3-af44-4c6f280d3fae (b921b045-1df0-41c3-af44-4c6f280d3fae) guid: a0b81ad7-47ec-4181-8b1f-733702fdd8c6 4 0x00061800 0x00747bff "userfs" attrs: 0x0000000000000000 type: b0e01050-ee5f-4390-949a-9101b17104e9 (b0e01050-ee5f-4390-949a-9101b17104e9) guid: cd07e31f-4090-499c-a02b-7966aa57b421 The "boot"-partition contains the Linux- image and device trees. To store the firmware binary into that partition we use the USB Mass Storage U-Boot function to mount that partition to our Linux host PC: .. prompt:: :prompts: U-Boot> ums 0 mmc 0:2 Mount the mass storage device on your host machine and copy the firmware .elf-file to the mounted boot-partition. Stop the ums-device with :kbd:`CTRL` + :kbd:`C` in U-Boot. List the contents of the boot-partition from U-Boot to check it: .. prompt:: :prompts: U-Boot> ls mmc 0:2 .. code-block:: text 16289800 Image 1302 stm32mp25-karo-copro.dtb 432 stm32mp25-karo-gpu.dtb 531 stm32mp25-karo-rtc.dtb 1075 stm32mp25-txmp-fdcan1.dtb 1075 stm32mp25-txmp-fdcan2.dtb 911 stm32mp25-txmp-ft5x06.dtb 1144 stm32mp25-txmp-keypad.dtb 7138 stm32mp25-txmp-lcd-panel.dtb 903 stm32mp25-txmp-mb7-wakeup-btn.dtb 1244 stm32mp25-txmp-mb7.dtb 432 stm32mp25-txmp-sdcard1-cd.dtb 432 stm32mp25-txmp-sdcard2-cd.dtb 4314 stm32mp25-txmp-sound.dtb 625 stm32mp25-txmp-spidev.dtb 97656 stm32mp257f-txmp-2550.dtb 3412056 OpenAMP_TTY_echo_CM33_NonSecure.elf Create a firmware folder named **/lib/firmware** inside your rootfs if it does not already exist. Copy the firmware image **OpenAMP_TTY_echo_CM33_NonSecure.elf** into the firmware folder .. code-block:: text mkdir /lib/firmware cp /media/OpenAMP_TTY_echo_CM33_NonSecure.elf /lib/firmware/ How to Control the Coprocessor from Linux ========================================= Basicly the Linux framework expects the firmware for the Cortex®-M334 coprocessor stored in the file system, by default in the */lib/firmware/* folder. Optionally another location can be set. In this case the remoteproc framework parses this new path in priority. Below the command for adding a new path for firmware parsing: .. prompt:: :prompts: # echo -n > /sys/module/firmware_class/parameters/path To load the firmware into the coprocessor by the remoteproc framework, use this command: .. prompt:: :prompts: # echo -n > /sys/class/remoteproc/remoteproc0/firmware Start the firmware with this comand: .. prompt:: :prompts: # echo start >/sys/class/remoteproc/remoteproc0/state This stops the remote processor: .. prompt:: :prompts: # echo stop >/sys/class/remoteproc/remoteproc0/state For debugging the remote processor you can get debug messages via the remoteproc framework: .. prompt:: :prompts: # cat /sys/kernel/debug/remoteproc/remoteproc0/trace0 dynamic debugging ================= In case of problems, you can enable dynamic debugging to obtain valuable information. .. prompt:: :prompts: # echo -n 'file stm32-ipcc.c +p' > /sys/kernel/debug/dynamic_debug/control echo -n 'file stm32_rproc.c +p' > /sys/kernel/debug/dynamic_debug/control echo -n 'file remoteproc*.c +p' > /sys/kernel/debug/dynamic_debug/control echo -n 'file virtio_rpmsg_bus.c +p' > /sys/kernel/debug/dynamic_debug/control echo -n 'file virtio_ring.c +p' > /sys/kernel/debug/dynamic_debug/control