PMU Firmware
This page provides information related to the Zynq UltraScale+ MPSoC Platform Management Unit (PMU). The PMU controls the power-up, reset, and monitoring of resources within the system.
Table of Contents
- 1 Overview of PMU Firmware
- 2 Modules
- 3 Inter-Processor Interrupts(IPI) Handling in PMUFW
- 4 Building PMU Firmware using Vitis
- 5 Debugging PMU FW using Vitis
- 6 Loading PMU Firmware in JTAG boot mode
- 7 Loading PMU Firmware in SD boot mode
- 8 PMU FW Build Flags
- 9 Power Management in PMU FW
- 10 Error Handling in PMU FW
- 11 Adding a Custom Module
- 12 CSU Runtime Services through PMU Firmware
- 13 PMU Firmware Memory Footprint
- 14 Registers reserved for PMU Firmware
- 15 Revision History
- 16 Related Links
Overview of PMU Firmware
The Platform Management Unit (PMU) in Zynq MPSoC has a Microblaze with 32 KB of ROM and 128 KB of RAM. The ROM is pre-loaded with PMU Boot ROM (PBR) which performs pre-boot tasks and enters a service mode. For more details on PMU, PBR and PMUFW load sequence, refer to Platform Management Unit (Chapter-6) in Zynq MPSoC TRM (UG1085). PMU RAM can be loaded with a firmware (PMU Firmware) at run-time and can be used to extend or customize the functionality of PMU. Some part of the RAM is reserved for PBR, leaving around 125.7 KB for PMU Firmware.
Here is the memory layout of PMU RAM:
The PMU Firmware provided in Vitis, comes with a default linker script which aligns with this memory layout and there is no specific customization required from user.
Note: As the PMU RAM size is 128KB, it is not possible to fit in all the supported features. Hence, some features are disabled by default. If the user requires any of the disabled feature and if it cannot fit in the PMU RAM, it is advised to disable other features which are enabled by default.
Modules
PMU Firmware is designed to be modular and enables adding new functionality in the form of modules. Each functionally distinct feature is designed in as a module, so that PMUFW can be configured to include only the required functionality for a user application. This type of modular design allows easy addition of new features and as well as optimizes memory footprint by disabling unused modules.
All the common functions that may be required by the modules are organized as separate libraries in PMUFW with APIs clearly specified. The included APIs in PMU Firmware are given below:
These APIs can be used by the modules in PMUFW to perform the specified actions as required.
Each module can be provided with three handlers which are called in during the respective phases as described below:
Module Handler | Purpose | API for Registering the Handler | execution context |
Init | Called during the init of the core to configure the module, register for events or add scheduler tasks. This can be used to load the configuration data into the module if required. | XPfw_CoreSetCfgHandler(const XPfw_Module_t *ModPtr, XPfwModCfgInitHandler_t CfgHandler); | StartUp |
Event Handler | Called when an event occurs (module should have registered for this event, preferably during the init phase | XPfw_CoreSetEventHandler(const XPfw_Module_t *ModPtr, XPfwModEventHandler_t EventHandler); | Interrupt |
IPI Handler | Called when an IPI message with respective module-id arrives | XPfw_CoreSetIpiHandler(const XPfw_Module_t *ModPtr, XPfwModIpiHandler_t IpiHandler, u16 IpiId); | Interrupt |
PMUFW has a default set of modules which address most of the common use case for Power Management and Error Management. these modules can be taken as references for implementation of custom modules.
Inter-Processor Interrupts(IPI) Handling in PMUFW
PMU has 4 Inter-Processor Interrupts(IPI) assigned to it and one set of buffers. By default, PMUFW uses IPI-0 and associated buffers for all message exchange with other processors on the SoC. PMUFW uses IPI driver to send and receive messages. An IPI manager layer is implemented over the driver and it takes care of dispatching the IPI message to the registered module handlers based on IPI ID in the first word of the message. The message format for IPI is given below:
Word | Content | Description |
0 | Header | <target_module_id, api_id> |
1 | PAYLOAD | Module dependent payload |
2 | ||
3 | ||
4 | ||
5 | ||
6 | RESERVED | RESERVED – for future use |
7 | Checksum |
IPI-1 is used for the callbacks from PMU to other masters and for communication initiated by PMUFW.
Currently, PM and EM modules use IPIs and this can be taken as reference for implementing custom modules which require IPI messaging.
Building PMU Firmware using Vitis
For tips configuring PMU firmware builds in PetaLinux see PetaLinux Yocto Tips.
Open Vitis
Create a new application with File->New→Application Project...:
Enter project name and click on Next. Eg: pmufw
Select platform as "zcu102" from "Create a new platform from hardware (XSA)" tab options. Click on Next
Now select the domain option as below and click on next
CPU: psu_pmu_0
OS: standalone
Language: C
Select "ZynqMP PMU Firmware" template from Templates list and click on Finish.
After this, PMU project will be created. Right click on the project and select "Build Project" to build PMU Firmware.
Connect to the local board and test the connection. You should see a pop up showing that the connection was established successfully.
Connect to the COM port on the terminal to view the UART prints.
On XSCT Console, Connect to the board and Run the PMU firmware.
View the PMU firmware prints on the Terminal console
Debugging PMU FW using Vitis
PMU FW will be built with -Os and LTO optimizations by default.
If the user need to disable the optimization (for debugging), two things need to be done:
Since removing optimization results in increase of code size and can result in not being able to build PMU FW, some of the features that the user don’t use, need to be disabled by removing build flags from project settings. And to further disable some features, it can be disabled in xpfw_config.h file of PMU FW
To disable/modify Optimizations, below changes need to be done:
PMU FW application: In "Miscellaneous" section, need to remove/modify highlighted options below:
It has to be noted that the compiler “Optimization” screen in Vitis cannot sense the optimization selected through “Miscellaneous” flags screen (above). This means “Optimization” screen still shows “-O0”, which can be misleading to the users (as shown below).
Below are the steps to debug PMU FW application using Vitis:
Right click on the application to "Debug As" and click on “Debug Configurations”.
Right click on System Debugger and Click "New". You get a "New Configuration". Click on Debug.
You will now see the debug perspective and PMU firmware will run.
Place the break points to control the flow and rerun for debugging.
Loading PMU Firmware in JTAG boot mode
From 2017.1, PM operations depend on the configuration object loaded by FSBL. So it is mandatory to load PMU FW before loading FSBL. This is taken care in device boot modes, but in JTAG boot mode, user need to specifically ensure this.
Following are the steps for JTAG boot mode:
For Silicon v3.0 and above, PMU Microblaze is not visible in xsdb. Hence disable security gates to view PMU Microblaze
Load PMU FW and run
Load FSBL and run
Continue with U-Boot/Linux/user specific application
Following is the complete TCL script:
#Disable Security gates to view PMU MB target
targets -set -filter {name =~ "PSU"}
mwr 0xffca0038 0x1ff
after 500
#Load and run PMU FW
targets -set -filter {name =~ "MicroBlaze PMU"}
dow xpfw.elf
con
after 500
#Reset A53, load and run FSBL
targets -set -filter {name =~ "Cortex-A53 #0"}
rst -processor
dow fsbl_a53.elf
con
#Give FSBL time to run
after 5000
stop
#Other SW...
dow u-boot.elf
dow bl31.elf
conLoading PMU Firmware in SD boot mode
Note: When PMUFW is loaded in a non-JTAG Boot mode on a 1.0 Silicon, an error message "Error: Unhandled IPI received" may be logged by PMUFW at startup, which can be safely ignored. This is due to the IPI0 ISR not being cleared by PMU ROM which is fixed in 2.0 and later versions of Silicon.
PMU Firmware can be loaded by either FSBL or by CSU BootROM (CBR). Both these flows are supported by Xilinx. PMU Firmware loading by CBR will be needed in the cases where the customer board has an onboard regulator that needs to be programmed to bring up the boot processor's power rail. Loading PMU Firmware using FSBL has these benefits: (i) Possible quick boot time, when PMUFW is loaded after bit-stream, (ii) In use cases where the user want two BIN files - stable and up-gradable, PMUFW can be part of the up-gradable (by FSBL) image.
Using FSBL to load PMU FW
Note: This method of loadind PMUFW (versus loading by CBR) is necessary to see any early prints issued by PMUFW during initialization.
We already have pmufw.elf with us. ( See building PMU FW at the top of this page)
Build an FSBL in the Vitis for A53. ( R5 can also be used)
Create a hello_world example for A53. Right Click on the "hello_world example" project and select "Create a boot image"
Create a new bif file. Choose
Architecture : ZynqMP
You will see A53 fsbl and hello_world example by default in partitions. We need pmufw too.
Click on Add, then provide pmufw.elf path. Also Partition type: datafile, Destination device : PS, Destination CPU : PMU
Click OK.
After adding pmufw as partition. Click on pmufw partition and click UP bottom.
Make sure partition order
A53 fsbl
pmufw
hello world App
Click on Create Image. You will see BOOT.bin created in a new folder "bootimage" in your example project.
View the .BIF file to confirm the partition order.
Now copy this BOOT.bin into SD card.
Boot the ZCU102 board in SD boot mode. You can see the fsbl -> pmufw ->hello_world example prints in a sequence.
Using CBR to load PMU FW
Note: When PMUFW is loaded by CBR, it is executed prior to FSBL. So the MIOs, Clocks and other initializations are not done at this point and this means that the PMUFW banner and other prints may not be seen prior to FSBL.
Post FSBL execution, the PMUFW prints can be seen as usual.
To make CBR load pmufw, we just need to change the BOOT.bin boot partitions.
Now steps listed above (1 -> 3) are same.
Create a new bif file. Choose
Architecture : ZynqMP
You will see A53 fsbl and hello_world example by default in partitions. We need pmufw too.
Click on Add, then provide pmufw.elf path. Also Partition type: pmu (loaded by bootrom).
Click OK.
Click on Create Image. You will see BOOT.bin created in a new folder "bootimage" in your example project.
You can also view .BIF to confirm the partition order.
Now copy this BOOT.bin into SD card.
Boot the ZCU102 board in SD boot mode. You can see the pmufw -> fsbl ->hello_world example prints in a sequence.
PMU FW Build Flags
Flag | Description | Requires these flags/build options to be enabled | Default setting |
XPFW_DEBUG_DETAILED | Enables detailed debug prints in PMU Firmware Additionally, see Using FSBL to load PMUFW regarding necessary configuration to see early prints during initialization. | Disabled | |
PM_LOG_LEVEL | This enables print based debug functions for PM module. Possible values are:
Higher numbers include the debug scope of lower number, i.e: enabling 3 (warnings) also enables 1 (alerts) and 2 (errors) Additionally, see Using FSBL to load PMUFW regarding necessary configuration to see early prints during initialization. | Disabled | |
ENABLE_EM | Enables Error Management Module | ENABLE_SCHEDULER | Disabled |
ENABLE_ESCALATION | Enables escalation of sub-system restart to SRST/PS-Only if the first restart attempt fails | ENABLE_RECOVERY | Disabled |
ENABLE_RECOVERY | Enables WDT based restart of APU sub-system | ENABLE_EM, ENABLE_SCHEDULER, ENABLE_PM | Disabled |
ENABLE_NODE_IDLING | Enables idling and reset of nodes before force shutdown of a sub-system | Disabled | |
ENABLE_PM | Enables Power Management Module | Enabled | |
ENABLE_SCHEDULER | Enables Scheduler Module | Enabled | |
ENABLE_WDT | Enables WDT based restart functionality for PMU using CSU WDT | ENABLE_SCHEDULER, ENABLE_EM | Disabled |
ENABLE_CUSTOM_MOD | Enables custom module which is a placeholder for user | Disabled | |
ENABLE_STL | Enables STL Module | Disabled | |
ENABLE_RTC_TEST | Enables RTC Event Handler Test Module | Disabled | |
ENABLE_SAFETY | Enables CRC calculation for IPI messages | Disabled | |
ENABLE_FPGA_LOAD | Enables FPGA bitstream loading | ENABLE_PM | Enabled |
ENABLE_SECURE | Enables security features | ENABLE_PM | Enabled |
XPU_INTR_DEBUG_PRINT_ENABLE | Enables debug prints for XMPU/XPPU error handling see Using FSBL to load PMUFW regarding necessary configuration to see early prints during initialization. | ENABLE_EM | Disabled |
DEBUG_MODE | Enable debug logging and prints See Using FSBL to load PMUFW regarding necessary configuration to see early prints during initialization. | Disabled | |
DEBUG_CLK | Enables dumping clock and PLL state functions | ENABLE_PM | Disabled |
DEBUG_PM | Enables debug functions for PM | ENABLE_PM | Disabled |
IDLE_PERIPHERALS | Enables idling peripherals before PS or System reset | ENABLE_PM | Disabled |
ENABLE_POS | Enables Power Off Suspend feature | ENABLE_PM | Disabled |
EFUSE_ACCESS | Enables eFuse access feature | ENABLE_PM | Disabled |
ENABLE_MOD_ULTRA96 | Enable power button functionality for ULTRA96 board | ENABLE_PM, ENABLE_SCHEDULER | Disabled |
ENABLE_SMMU | Bypass SMMU functionality in the firmware during suspend and rewoke the same when resume. | Disabled | |
PMU_MIO_INPUT_PIN | Enables board shutdown related code | Disabled | |
EXT_RESET_MIO_PIN_VAL | Board external reset MIO pin (32-37). For K26 and K24 by default it is configured as 35. | Disabled | |
EXT_RESET_MIO_PIN_STATE_VAL | Board external reset MIO pin active state (0-1). | Disabled | |
ENABLE_CSU_MULTIBOOT | Enables CSU multiboot functionality for A/B image partition. | Disabled | |
DISABLE_UART_IDLING | Skips UART idling for WDT restart use cases | Please refer to MPSoC Restart Solution page | Disabled |
ENABLE_SECURE_FLAG | Validates the requested command is secure or not before proceeding with an operation | Enabled | |
ENABLE_MEM_RANGE | Validates the memory range for a requested master before proceeding with an operation | Enabled | |
ENABLE_MEM_RANGE_PM_SET_CONFIG | Validates the config object mem-range details | ENABLE_MEM_RANGE | Disabled |
ENABLE_MEM_RANGE_PM_SELF_SUSPEND | Validates the suspend address | ENABLE_MEM_RANGE | Disabled |
ENABLE_MEM_RANGE_PM_REQUEST_WAKEUP | Validates the resume address | ENABLE_MEM_RANGE | Disabled |
Note: To enable the platform specific build flag please refer below:
Zynq UltraScale+ MPSoC Restart solution#ModifyingPlatformSpecificBuildFlags
Important note: Not all combinations of build flags will fit in the PMU RAM. Enabling some features will require disabling others. For example, enabling EFUSE_ACCESS may require disabling ENABLE_FPGA_LOAD. Refer to PMU Firmware Memory Footprint section for some examples.
Power Management in PMU FW
Zynq MPSoC Power Management framework is based on an implementation of the Embedded Energy Management Interface (EEMI). This framework allows software components running across different processing units (PUs) on a chip or device to issue or respond to requests for power management.
The PM module is implemented within the PMU firmware as an event-driven module. Events processed by the PM module are called power management events. All power management events are triggered via interrupts. When handling an interrupt the PMU firmware determines whether the associated event shall be processed by the PM module. Accordingly, if the PMU firmware determines that an event is power management related and if the PM module is enabled the PMU firmware triggers it to process the event.
When processing a power management event the PM controller may exploit the PMU ROM handlers for particular operations regarding the state control of hardware resources. Refer to Zynq Power Management Framework User Guide(UG1199) for details.
PM Configuration Object
The configuration object is a binary data object used to allow updating data structures in the PMU firmware power management module at boot time. The configuration object must be copied into memory by a processing unit on the Zynq UltraScale+ MPSoC. The memory region containing the configuration object must be accessible by the PMU.
The configuration object specifies:
© 2025 Advanced Micro Devices, Inc. Privacy Policy