System Controller Firmware 101 - Resource management service

显示  仅  | 搜索替代 

System Controller Firmware 101 - Resource management service


System Controller Firmware 101 - Resource management service

The resource management service offers the possibility to divide the system into groups of resources or partitions. Resources within a partition can not access resources outside of it's partition.

Partitioning a system is useful to isolate resources from one another, this gives you the ability to have for instance FreeRTOS and Linux each running simultaneously with its own set of resources. In the FreeRTOS/Linux example you could partition/divide the system into two groups/partitions where all resources/peripherals needed by FreeRTOS would be completely isolated from the resources needed by Linux, if any of the resources on the Linux partition tried to access a resource on the FreeRTOS partition the transaction would result in a bus error, as if the resource tried to access a region outside of its memory map.

The partitioning mechanism is enforced by hardware and the configuration of the underlying hardware is completely abstracted by the SCFW API. The system partitioning can be performed in two ways:

  • At boot time by modifying the function board_system_config on the board.c portion of the SCFW porting kit that corresponds to your board. This is used for software that is loaded as part of the boot process.
  • At run time by calling the resource management service functions available. This is used to partition software that is launched by an operating system, e.g. an M4 used as sensor fusion and loaded/started by Linux.

A partition can have:

  • Resources (peripherals)
  • Pads
  • Memory regions

All of the items mentioned above can be grouped within a partition.

It is important to note that:

  • At boot time all resources are grouped into a single partition.
  • Resources can only be assigned to another partition by a resource within it's own partition. 

Initial partitioning state of the system

At boot time the system is initially configured in three partitions:


  • The first partition (SCFW) contains all the resources, pads and memory required by the System Controller Unit (SCU) to execute the System Controller Firmware.
  • The second partition (SECO) contains all the resources required by the Security Controller to execute.
  • The third partition (Boot) contains all of the remaining resources, pads and memory available for the whole system.

Once Linux and the M4 boot a typical use case is to partition the system as follows:


In this case the boot partition is split into the ATF/Linux partition and the M4 partition.

The ARM Trusted Firmware environment add a layer of abstraction to secure the environment and it is assigned cores and memory to execute in this privileged state, all the remaining resources, pads and memory are assigned to the Linux partition.

The M4 partition contains all the resources required by the M4 to execute, as well as the resources required by the application running on the M4.

Resource partitioning - Boot time configuration

The SCFW porting kit provides an example on doing boot time configuration at the board.c file under platform/board/mx8q<x or m>_<your board>/board.c, board_system_config is the function in charge of partitioning the system at boot time.

From the sc_fw_port.pdf (porting guide) document included in the porting kit - Boot Flags chapter:


Here are a few important points to highlight:

  • The code will only execute if the SC_BD_FLAGS_ALT_CONFIG is set under the boot flags (more details in the Usage chapter of the sc_fw_port.pdf), the flags are set while building the image with mkimage. An example is provided to build an image with partitioning enabled:
flash_linux_m4: $(MKIMG) mx8qx-ahab-container.img scfw_tcm.bin u-boot-atf.bin m4_image.bin
 ./$(MKIMG) -soc QX -rev B0 -append mx8qx-ahab-container.img -c -flags 0x00200000 -scfw scfw_tcm.bin -ap u-boot-atf.bin a35 0x80000000 -p3 -m4 m4_image.bin 0 0x34FE0000 -out flash.bin‍‍‍‍‍‍‍‍‍‍‍‍

The example above can be found under your i.MX8 variant on the soc.mak file, in the example above the SC_BD_FLAGS_ALT_CONFIG flag is being set by -flags 0x00200000 and the partition for the M4 is defined as the third one by the -p3 parameter.

Without the -flags 0x00200000 (setting SC_BD_FLAGS_ALT_CONFIG) parameter on mkimage NO partition happens at boot time, if the target used to build the image does not set this flag, then the SCU does not partition the system.

On the board.c file the code in charge of checking for this flag is the following:

/* Configure initial resource allocation (note additional allocation
 and assignments can be made by the SCFW clients at run-time */
 if (alt_config != SC_FALSE)

if the alt_config flag is not set, then the partitioning is skipped.

  • The function rm_dump(pt_boot); dumps the partitioning state of the whole system, it can be called before and after the partitioning to make sure the device was partitioned as expected. Here is how a partition dump looks like:
*** Partitions **********************************
 Partition: 0
 Parent: 0
 DID: 2
 Partition: 1
 Parent: 0
 DID: 0
 Partition: 2
 Parent: 0
 DID: 1

*** Resources ***********************************
 Partition: 0
 ... Continues ....
 Partition: 1
 ... Continues ....
 Partition: 2

*** Memory Regions ******************************
Partition: 0
 000: 0x030FE0000 - 0x03101FFFF
Partition: 1
 001: 0x000000000 - 0x01BFFFFFF
 002: 0x034000000 - 0x037FFFFFF
 003: 0x038000000 - 0x03BFFFFFF
 004: 0x060000000 - 0x06FFFFFFF
 005: 0x070000000 - 0x07FFFFFFF
 006: 0x080000000 - 0x0FFFFFFFF
 007: 0x400000000 - 0x43FFFFFFF
 008: 0x880000000 - 0xFFFFFFFFF
Partition: 2

*** Pads ****************************************
 Partition: 0
 ... Continues ....
 Partition: 1
 ... Continues ....
 Partition: 2‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The dump contains the configuration of the partition, for instance:

*** Partitions **********************************
 Partition: 0
 Parent: 0
 DID: 2

On the example above the Partition parent is partition 0 (itself, this is the System Controller partition, all partitions spawn from this one). The Domain ID (DID) is 2, this ID is used to identify the partition by the hardware, it is used to enforce hardware isolation. It is also a secure and isolated partition, the meaning of these flags can be found below and in the sc_fw document:

  • Secure - boolean indicating if this partition should be secure; only valid if caller is secure
  • Isolated - boolean indicating if this partition should be HW isolated; set SC_TRUE if new DID
    is desired
  • Restricted - boolean indicating if this partition should be restricted; set SC_TRUE if masters in this
    partition cannot create new partitions
  • Grant - boolean indicating if this partition should always grant access and control to the parent
  • Coherent - boolean indicating if this partition is coherent; set SC_TRUE if only this partition will contain
    both AP clusters and they will be coherent via the CCI

The rest of the sections of the dump highlight all the resources, pads and memory regions enclosed in each partition.

  • For more details on the definition of all the API calls please refer to the respective sc_fw_api document for each SoC variant.

Resource partitioning - Run time configuration 

The run time partitioning doesn't differ from the example provided on the porting kit, that example can be used as a base to create a partition at run time by calling the SCFW API. 


The following examples will show how to modify the default partition configuration on the evaluation boards, i.MX8QM MEK will be used as a reference. With BSP 4.14.98_2.3.0, the porting kit can be obtained from i.MX Software and Development Tools | NXP .


Default configuration without partitioning

First we will dump the default configuration without partition, e.g. without setting the ALT_CONFIG flag, most mkimage targets with a single image are configured this way, see the soc.mak and related files under scripts:

soc.mak\iMX8QM - imx-mkimage - i.MX Mkimage Bootloader Tool 

For details on how to create a bootable image see i.MX8 Boot process and creating a bootable image 

We can see that the targets flash and flash_spl do not set any flags on the image, therefore no partition of the system will occur at boot time.

flash: $(MKIMG) $(AHAB_IMG) scfw_tcm.bin u-boot-atf.bin
 ./$(MKIMG) -soc QM -rev B0 -append $(AHAB_IMG) -c -scfw scfw_tcm.bin -ap u-boot-atf.bin a53 0x80000000 -out flash.bin‍‍‍‍

We will build the SCFW with the Debug Monitor enabled in order to be able to dump the partitions:

make qm R=B0 B=mek M=1‍‍‍

Now we copy the SCFW binary we just build (scfw_tcm.bin under build_mx8qm_b0) to the mkimage iMX8QM folder, along with the SECO FW, ATF (bl31.bin) and u-boot.

On mkimage the flash target will be used to create a bootable image with the SCFW we just build:

make SOC=iMX8QM flash‍‍‍‍

Flash the image to your sd card

sudo dd if=iMX8QM/flash.bin of=/dev/mmcblkXX bs=1k seek=32

The MEK has two serial ports, the first one (usually ttyUSB0) is used by the A cores (u-boot/Linux in this case), the second one is used by one of the M4 cores OR the SCFW, in this case it will be used by the SCFW. 

Unfortunately there aren't enough serial ports on the MEK board to allow a dedicated port for SCU, M4 cores and A cores, so in order to use the Debug Monitor on the MEK the SCFW has to take over the M4_0 UART terminal.

On the SCFW Debug monitor terminal type "dump rm" this will dump all the partition information, the full log is attached to this document (imx8qm_mek_no_partition.txt). On this log it can be seen that 4 partitions are created:

Partition 0 --> SCFW

Partition 1 --> ATF

Partition 2 --> SECO

Partition 3 --> U-boot/Linux/M4 cores/Rest of the system

The ATF partition is created at run time by the ATF to run in its secure state, no extra partition is created at boot time, if an image without ATF where to be used only three partitions would be seen:

Partition 0 --> SCFW

Partition 1 --> U-boot/Linux/M4 cores/Rest of the system

Partition 2 --> SECO

Default configuration with partitioning enabled

Now we will create an image with the SC_BD_FLAGS_ALT_CONFIG flag set, so that partitioning occurs at boot time, for demonstration purpose we will use the same target previously used but we will modify it to set the ALT_CONFIG flag, so on mkimage modify the flash target as follows:

On iMX8QM/soc.mak

flash: $(MKIMG) $(AHAB_IMG) scfw_tcm.bin u-boot-atf.bin
 ./$(MKIMG) -soc QM -rev B0 -append $(AHAB_IMG) -c -flags 0x00200000 -scfw scfw_tcm.bin -ap u-boot-atf.bin a53 0x80000000 -out flash.bin‍‍

After the modification build the image again

make clean
make SOC=iMX8QM flash‍‍

On mkimage's output you should be able to see:

FLAG: 0x00200000

Note how the same SCFW is used as in the previous example, same for ATF, SECO, U-boot the only required change in this case is to enable the ALT_CONFIG flag in the image.

Flash the sd card with the new image

sudo dd if=iMX8QM/flash.bin of=/dev/mmcblkXX bs=1k seek=32

Dumping again the partitioning on the Debug monitor shows how the system now created additional partitions for the M4 cores and a shared partition:

Partition 0 --> SCFW

Partition 1 --> ATF (Created at run time by the ARM Trusted Firmware)

Partition 2 --> SECO

Partition 3 --> M4_0

Partition 4 --> M4_1

Partition 5 --> Shared partition

Partition 6 --> U-boot/Linux/rest of the system

The full log is attached as well.

Modifying default configuration

Now we will modify the default SCFW configuration to move some resources/pads from the M4 partition to the A cores partition (u-boot/Linux).

All FlexCAN resources and pads will be moved from the M4 partition to the A core partition.

From sc_fw_api_qm_b0.pdf Resource List:


From sc_fw_api_qm_b0.pdf Pad List:


Not all resources are available on all variants, for details on what resources/pads are available on your device please refer to its respective api document.

Go back to the SCFW porting kit and open platform/board/mx8qm_mek/board.c, go to the definition of board_system_config which is the function where partitioning occurs.

The code first verifies if the alt_config flag is set, and if not it skips partitioning, so all partitioning happens within the following if statement:

/* Configure initial resource allocation (note additional allocation
 and assignments can be made by the SCFW clients at run-time */
 if (alt_config != SC_FALSE)

The following partitions and memory regions are declared within this if statement:

sc_rm_pt_t pt_m4_0;
 sc_rm_pt_t pt_m4_1;
 sc_rm_mr_t mr_m4_0, mr_m4_1;
 sc_rm_pt_t pt_sh;
 sc_rm_mr_t mr_sh;‍‍‍‍‍‍‍‍‍‍

pt_m4_0 is the partition for the M4_0 core, its memory region is declared as mr_m4_0.

Likewise for the M4_1 pt_m4_1 and mr_m4_1 are the partitions and memory regions assigned to the M4.

pt_sh and mr_sh are the shared partition and memory region.

A shared partition is created but it can only have a shared memory region. Pads and resources CANNOT BE SHARED there is no mechanism to protect the pads and resources from contention, if access to a resource is required by multiple partitions a virtual resource needs to be created, in this way the partition that requires access asks the partition that owns the resource to configure/use the resource on its behalf. See the VIRT_I2C example on the Linux BSP.

The partition that hosts all remaining resources is the pt_boot partition, this can be seen as the A cores partition, all resources and memory regions not assigned to the M4 partitions will be left on the pt_boot partition where the A cores are.

The code is documented well and self-explanatory, for instance the following line marks all resources within the M4_0 subsystem to be moved to the M4_0 partition:

/* Mark all M4_0 subsystem resources as movable */
 BRD_ERR(rm_set_subsys_rsrc_movable(pt_boot, SC_R_M4_0_PID0,
 BRD_ERR(rm_set_pad_movable(pt_boot, SC_P_M40_I2C0_SCL,
 SC_P_M40_GPIO0_01, SC_TRUE));

The resource list in the sc_fw_api_qm_b0.pdf document shows what resources belong to the M4 subsystem:


Next some other resources required by the M4 are assigned to its partition, such as MUs used to communicate with the other cores, timers and the IRQ steer resource.

In this case we are interested on having the FlexCAN resources/pads on the A cores side, these resources/pads are being assigned to the M4_1 partition as can be seen on the previous partitions dumps and the following code:

/* Move some resources not in the M4_1 subsystem */
 BRD_ERR(rm_set_resource_movable(pt_boot, SC_R_IRQSTR_M4_1,
 BRD_ERR(rm_set_resource_movable(pt_boot, SC_R_UART_2,
 BRD_ERR(rm_set_pad_movable(pt_boot, SC_P_UART0_CTS_B,
 BRD_ERR(rm_set_resource_movable(pt_boot, SC_R_MU_6B,
 BRD_ERR(rm_set_resource_movable(pt_boot, SC_R_MU_7B,
 BRD_ERR(rm_set_resource_movable(pt_boot, SC_R_MU_9B,
 BRD_ERR(rm_set_resource_movable(pt_boot, SC_R_GPT_3,
 BRD_ERR(rm_set_resource_movable(pt_boot, SC_R_CAN_0,
 BRD_ERR(rm_set_resource_movable(pt_boot, SC_R_FSPI_0,

 /* Move some pads not in the M4_1 subsystem */
 BRD_ERR(rm_set_pad_movable(pt_boot, SC_P_FLEXCAN0_RX,
 BRD_ERR(rm_set_pad_movable(pt_boot, SC_P_QSPI0A_DATA0,

Previous dump:

*** Resources ***********************************

Partition: 4

*** Pads ****************************************

Partition: 4

So we just need to remove the following lines from the board.c:

BRD_ERR(rm_set_resource_movable(pt_boot, SC_R_CAN_0,

 BRD_ERR(rm_set_pad_movable(pt_boot, SC_P_FLEXCAN0_RX,

That way the resources/pads won't be marked to be moved to the M4_1 partition and they will be left on the pt_boot partition (A core partition). If a resource needs to be added to the M4 partition just add the calls to rm_set_resource_movable to assign it.

Now we just need to rebuild the scfw and our image:

make qm R=B0 B=mek M=1‍‍‍‍

Then on mkimage (with the flags set modification above):

make SOC=iMX8QM flash‍‍‍

Flash the sd card with the new image:

sudo dd if=iMX8QM/flash.bin of=/dev/mmcblkXX bs=1k seek=32

Now when the dump is done we can see that the FlexCAN resources and pads belong to the same partition as the A cores (partition 6).

*** Resources ***********************************

Partition: 6




*** Pads ****************************************

Partition: 6




The device tree would still need to be modified to configure the pads and FlexCAN resources.

System Controller Firmware 101 

‎09-10-2020 02:57 AM