cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
rmx01
Observer
Observer
1,059 Views
Registered: ‎05-09-2017

ZynqMP: Duration of an RPU reset

I once used a Zynq UltraScale+ MPSoC evaluation board with an XCZU9EG-FFVC900-1-I-ES1 device.

During that time, I approximated the duration of an RPU reset by performing the following sequence:

  1. Invoke the XPfw_ResetRpu function from the PMU firmware.
  2. Store a PIT counter value within the PMU registers.
  3. Wait for an IPI that the RPU application sends to the PMU (immediately after starting up).
  4. Get another PIT value from the PMU.
  5. Consider the difference between the two PIT values.

For the ES1 device, I obtained an RPU reset duration of about 150 microseconds. When repeating the same experiment with a production device (XCZU9EG-FFVB1156-2-E), I measure an RPU reset duration of about 150 milliseconds. All involved clocks are at least as fast as in the easlier measurement.

 

Does anyone where this significant deviation might stem from? Maybe it's related of the BIST of the RPU?

0 Kudos
1 Reply
rmx01
Observer
Observer
1,003 Views
Registered: ‎05-09-2017

I have performed some further experiments in order to narrow the issue down. Unfortunately, I have not been able to solve it.

 

I'm running Vivado 2018.1 and switched to the default ZCU102 platform that the SDK offers (ZCU102_hw_platform). I have verified that TTC0 runs at a frequency of 100 MHz.

 

To trigger a reset of the RPU, I run the default PMU firmware (of 2018.1) with a custom module. This module initializes a TTC instance:

static XTtcPs TtcPs;

static void RstCfgInit(const XPfw_Module_t *ModPtr, const u32 *CfgData, u32 Len) { int Status; XTtcPs_Config *TtcPsConfig = XTtcPs_LookupConfig(XPAR_XTTCPS_0_DEVICE_ID); if (!TtcPsConfig) print("Error obtaining TTC configuration!\r\n"); Status = XTtcPs_CfgInitialize(&TtcPs, TtcPsConfig, TtcPsConfig->BaseAddress); if (Status != XST_SUCCESS) print("Error initializing the TTC instance!\r\n"); Status = XTtcPs_SelfTest(&TtcPs); if (Status != XST_SUCCESS) print("Error performing the self-test!\r\n"); XTtcPs_SetOptions(&TtcPs, 0); XTtcPs_Start(&TtcPs); }

At the same time, I've written a minimal RPU application that is supposed to be linked to the reset vector location (0x0). It does nothing but to read the TTC value into r5:

.global _boot
.section .boot,"ax"
_boot:
	ldr r0, _ttc
	ldr r5, [r0]
_loop:
	b _loop

_ttc: .word 0xff110018

Using an XSCT connection, I am able to trigger the following code on the PMU firmware:

// Trigger the RPU reset (see xpfw_resets.h)
XPfw_ResetRpu();

// Obtain and output the TTC value
xil_printf("%u\r\n", XTtcPs_GetCounterValue(&TtcPs));

After performing such a trigger, I calculate the difference between the counter value from r5 and the counter value that the PMU firmware has printed out right after initiating the RPU reset. For n = 10 iterations of that kind, I have calculated an average difference of 16745449.9 ticks (at a standard deviation of 545077.2 ticks).

 

Given that the TTC runs at 100 MHz, I conclude that after initiating an RPU reset from the PMU, it takes 167 (±5) ms before the reset vector of the RPU is executed. This appears to be a fairly long time interval to me. If possible, I would like to speed this up.

 

Unfortunately, I no longer have access to the ES1 device. But as I said before, I measured an RPU reset duration of less than 150 µs using it.

 

Is anyone able to reproduce this? Or knows about a way to get access to the relevant changelogs?

 

By the way, this is the disassembled code present at the RPU reset vector location:

xsct% dis 0x0 4
00000000: ldr     r0, [pc, #+4]
00000004: ldr     r5, [r0]
00000008: b       -8      ; addr=0x00000008: _loop
0000000c: .byte 0x18
0000000d: .byte 0x00
0000000e: .byte 0x11
0000000f: .byte 0xff

And this is the code that I have used to set the platform up after a POR:

source C:/Xilinx/SDK/2018.1/scripts/sdk/util/zynqmp_utils.tcl
source psu_init.tcl
targets -set -nocase -filter {name =~"APU*"}
psu_init
targets -set -nocase -filter {name =~"PSU*"}
catch {disable_pmu_gate}
targets -set -nocase -filter {name =~"MicroBlaze*PMU*"}
dow pmu.elf
con
targets -set -nocase -filter {name =~"*R5*0"}
rst -processor
catch {XFsbl_TcmEccInit R5_L}
dow rpu.elf
con

 Thank you very much in advance!

0 Kudos