ARMv7 PMU Event Counter Configuration and Initialization Issues
The ARMv7 Performance Monitoring Unit (PMU) is a powerful tool for profiling and analyzing system performance, particularly in embedded systems. However, a common issue arises when the event counters consistently return zero, while the cycle counter functions as expected. This problem often stems from improper configuration or initialization of the PMU registers, which can be subtle and difficult to diagnose without a deep understanding of the ARM architecture.
The PMU event counters are designed to track specific hardware events, such as cache misses, branch mispredictions, or instruction executions. When these counters return zero, it indicates that the events being monitored are either not occurring or, more likely, that the PMU is not correctly configured to capture them. The cycle counter, which measures the number of CPU cycles, is typically simpler to configure and often works out of the box, leading to confusion when the event counters fail to produce meaningful results.
To properly configure the PMU, several registers must be set up correctly. These include the PMUSERENR (User Enable Register), PMCR (Performance Monitors Control Register), PMSELR (Performance Monitors Event Counter Selection Register), and PMXEVTYPER (Performance Monitors Event Type Register). Each of these registers plays a critical role in enabling and configuring the PMU, and any misconfiguration can lead to the event counters returning zero.
For example, the PMUSERENR.E bit must be set to allow user-mode access to the PMU. Without this, any attempts to read or write PMU registers from user space will fail silently. Similarly, the PMCR.E bit must be set to enable the PMU globally. Additionally, the PMCR.C and PMCR.P bits are used to reset the cycle and event counters, respectively. If these bits are not set correctly, the counters may not start from zero or may not increment as expected.
The PMSELR register is used to select which event counter is being configured, while the PMXEVTYPER register specifies the type of event to be counted. If the event type is not supported by the hardware or is not correctly specified, the event counter will not increment. This is a common source of confusion, as the ARM architecture allows for a wide range of event types, but not all of them are supported on every processor.
Unsupported Event Types and PMCEIDx Register Verification
One of the most overlooked aspects of PMU configuration is verifying that the event type being monitored is actually supported by the hardware. This is done by reading the PMCEIDx (Performance Monitors Common Event Identification) registers. These registers provide a bitmap of supported events, with each bit corresponding to a specific event type. If the event type is not supported, attempting to configure it will result in the event counter remaining at zero.
In the case described, the user reported that the PMCEID0 register had a value of 0x7FFFFFFF, which indicates that a wide range of events are supported. However, this does not guarantee that the specific event being monitored is supported. The PMCEIDx registers are hierarchical, and some events may require additional configuration or may not be available in certain modes of operation.
For example, some events may only be available in privileged mode, while others may require specific hardware features to be enabled. If the event type is not supported, the PMU will not increment the corresponding event counter, even if the configuration appears correct. This can be particularly frustrating when following documentation or example code, as the supported events can vary between different ARM cores and implementations.
To verify that the event type is supported, it is essential to consult the processor’s technical reference manual (TRM) and cross-reference the event type with the PMCEIDx registers. If the event type is not supported, an alternative event type must be selected, or the profiling goals must be adjusted to align with the available events.
Platform-Specific Considerations and Debugging Steps
Another critical factor in PMU configuration is the platform being used. Different platforms may have unique requirements or limitations when it comes to PMU usage. For example, some platforms may require additional configuration steps, such as setting the SDER (Secure Debug Enable Register) to enable non-secure access to the PMU. In the case described, the user mentioned using an MTK platform with an ARMv7 Cortex-A53 processor. While the Cortex-A53 is a widely used core, the specific implementation on the MTK platform may have additional quirks or requirements.
When debugging PMU issues, it is essential to start with a minimal, reproducible test case. This involves isolating the code that configures and reads the PMU registers and running it in a controlled environment. If the issue persists, the next step is to verify that the PMU registers are being set correctly. This can be done by reading back the registers after writing them and comparing the values to the expected configuration.
If the registers are being set correctly but the event counters still return zero, the next step is to verify that the event type is supported and that the PMU is correctly enabled. This involves checking the PMCEIDx registers and ensuring that the PMCR.E bit is set. Additionally, it is important to verify that the PMU is not being disabled or reset by other parts of the system, such as power management features or secure boot processes.
Finally, if all else fails, it may be necessary to consult the platform’s documentation or contact the vendor for additional support. Some platforms may have proprietary extensions or limitations that are not documented in the ARM architecture reference manuals. In these cases, vendor-specific tools or firmware updates may be required to enable PMU functionality.
Implementing Correct PMU Configuration and Debugging Techniques
To resolve the issue of PMU event counters returning zero, a systematic approach to configuration and debugging is required. The following steps outline a proven methodology for ensuring that the PMU is correctly configured and that the event counters are functioning as expected.
First, ensure that the PMU is enabled at both the global and user levels. This involves setting the PMUSERENR.E bit to allow user-mode access and the PMCR.E bit to enable the PMU globally. Additionally, the PMCR.C and PMCR.P bits should be set to reset the cycle and event counters, respectively. This ensures that the counters start from a known state and are ready to begin counting.
Next, verify that the event type being monitored is supported by the hardware. This is done by reading the PMCEIDx registers and cross-referencing the event type with the supported events listed in the processor’s TRM. If the event type is not supported, select an alternative event type that aligns with the profiling goals.
Once the event type is confirmed to be supported, configure the PMSELR and PMXEVTYPER registers to select the event counter and specify the event type. It is important to read back these registers after writing them to ensure that the configuration has been applied correctly. If the registers do not reflect the expected values, there may be an issue with the write operation or with the platform’s handling of the PMU registers.
After configuring the PMU, run the code or algorithm being profiled and read the event counters. If the counters still return zero, verify that the PMU is not being disabled or reset by other parts of the system. This may involve checking power management settings, secure boot processes, or other platform-specific features that could interfere with PMU operation.
If the issue persists, consider using a debugger or trace tool to monitor the PMU registers in real-time. This can provide insight into whether the registers are being set correctly and whether the event counters are incrementing as expected. Additionally, some platforms may have proprietary tools or firmware updates that can assist in debugging PMU issues.
In conclusion, the issue of ARMv7 PMU event counters returning zero is often caused by improper configuration or initialization of the PMU registers. By following a systematic approach to configuration and debugging, it is possible to identify and resolve the underlying issues, enabling accurate and reliable performance profiling. Key steps include verifying that the PMU is enabled at both the global and user levels, confirming that the event type is supported by the hardware, and ensuring that the PMU registers are being set correctly. Additionally, platform-specific considerations and debugging tools can provide valuable insights and assistance in resolving PMU issues.