Hi Johannes, Hi Stefan,
What timer(s) is seL4 using already? I assume there should be other hardware timers left.
I'd assume that seL4 uses the GTC or the cpu private timer(s)? I must admit, that I didn't look into them - I just used the existing imx6 and imx7 targets for comparison. And although both do also have cpu private timer(s), they use different timers (epit and gpt) in the case of seL4/Genode. Therefore I was under the impression, that a dedicated (multi-purpose) timer is necessary.
Apart from the TTC, Zynq7000 offers a system watchdog and cpu watchdogs. Since watchdogs are normally used for the reset of chips/the system, I only looked into the last possibility, the TTC.
Have you double-checked all PLL settings and clock dividers in the slcr? I strongly assume you are working with wrong assumptions regarding your clocking values.
I made sure, that CPU_1x is used as input clock `write<CLK_CNTRL::SRC>(0);` but apart from that I didn't look into any clock settings. As recommended by you two I took a look at the SLCR registers…
My platform (Zybo) contains a 50MHz oscillator which drives all PLLs. I checked that the ARM PLL is used to drive the CPU clock (SRCSEL in ARM_CLK_CTRL -> 0) and read the DIVISOR (-> 2), FDIV (-> 26) and CLK_621 (-> 1) registers.
The CPU_1x clock generation should be as following (chapter 25.3): PS_CLK * PL_FDIV = ARM_PLL freq ARM_PLL freq / DIVISOR = CPU_6x4x CPU_6x4x / 6 or 4 = CPU_1x
Or with exact values: 50 MHz * 26 = 1.300 MHz 1.300 MHz / 2 = 650 MHz 650 MHz / 6 = 108 MHz
My tickrate should therefore be: 108.000 ticks/ms or when using a prescaler value of 2^6=128 => ~1688 ticks/ms Since the prescaler register uses the following formula count/2^(N+1), I set it to 0x5.
When using this calculations, the timer has less deviation but is also 1/2 too slow, e.g. sleeping 10s results in ~4.9s, 20s results in ~9.9s etc. When changing the prescaler value now to 0x6, the /2 problem is gone (of course).
Any ideas where I'm still wrong? And thanks for the hint regarding the clock - this was very helpful! :)
State of the current implementation [0] and [1].
Best regards, Alex
[0]: https://github.com/irgendwie/genode/blob/rtcr-19.08-ttc/repos/base/src/timer... [1]: https://github.com/irgendwie/genode/blob/rtcr-19.08-ttc/repos/base/src/timer...
Output of the registers:
[init -> timer] --- ARM_CLK_CTRL --- [init -> timer] SRCSEL=0 [init -> timer] DIVISOR=2 [init -> timer] ------- SLCR ------- [init -> timer] CLK_621_TRUE=1 [init -> timer] -------------------- [init -> timer] --- ARM_PLL_CTRL --- [init -> timer] PLL_FDIV=26 [init -> timer] --------------------