GlobalTimer: add support for starting timer with interrupt #108

Closed
morgan wants to merge 4 commits from morgan/zynq-rs:master into master
Owner

Summary

  • add start_with_interrupt for GlobalTimer

  • refactor mpcore

    • fix comp_enable typo
    • combine icdicer register into an array to make register control easier
  • add support for disabling individual interrupt

  • add GlobalTimer interrupt test to experiment for core0

    • tested on kasli_soc
  • Compilation check

    • nix build <variant> for szl, coraz7-experiments, zc706-experiments and kasli_soc-experiments. All compiled without warning

New experiment log

Zynq experiments
[    48.742291s]  INFO(experiments): Boot mode: SdCard
[    48.747071s]  INFO(experiments): Setup clock sources...
[    48.752277s] DEBUG(libboard_zynq::clocks::source): Set ARM_PLL to 1600000000 Hz
[    13.205717s] DEBUG(libboard_zynq::clocks::source): Set IO_PLL to 1000000000 Hz
[    13.215440s]  INFO(experiments): PLLs set up
[    13.219747s]  INFO(experiments): CPU Clocks: 799999992/399999996/266666664/133333332
[     0.000000s] DEBUG(libboard_zynq::clocks::source): Set DDR_PLL to 1066666666 Hz
[     0.007308s] DEBUG(libboard_zynq::ddr): DDR 3x/2x clocks: 533333328/355555552
[     0.014483s] DEBUG(libboard_zynq::ddr): DDR DCI clock: 10062892 Hz (divisors=2*53)
[     0.024392s]  INFO(libboard_zynq::ddr): memtest phase 0 (status: Normal)
511 MB Ok
[     1.374867s]  INFO(libboard_zynq::ddr): memtest phase 1 (status: Normal)
511 MB Ok
[     2.896332s]  INFO(libboard_zynq::ddr): memtest phase 2 (status: Normal)
511 MB Ok
[     4.416859s]  INFO(libboard_zynq::ddr): memtest phase 3 (status: Normal)
511 MB Ok
[     5.937361s]  INFO(experiments): Enable GlobalTimer interrupt on core0
GlobalTimer interrupting core0...
GlobalTimer interrupting core0...
[     6.046825s]  INFO(experiments): Disable GlobalTimer interrupt
[     6.052640s]  INFO(experiments): Send software interrupt to core0
Interrupting core0...
[     6.060626s]  INFO(experiments): Core0 returned from interrupt
Hello from core1!
Hello from core1!
0 -> 0
Hello from core1!
1 -> 1
Hello from core1!
2 -> 4
Hello from core1!
3 -> 9
Hello from core1!
4 -> 16
Hello from core1!
5 -> 25
Hello from core1!
6 -> 36
Hello from core1!
7 -> 49
Hello from core1!
8 -> 64
Hello from core1!
9 -> 81
[     6.090383s] DEBUG(libboard_zynq::eth): Eth TX clock for 125000000: 999999990 / 1 / 8 = 124999998
Eth on
[     7.137988s]  INFO(experiments): time:      7.137986s, rx: 0k/s, tx: 0k/s
[     8.144985s]  INFO(experiments): time:      8.144983s, rx: 0k/s, tx: 0k/s
[     9.151981s]  INFO(experiments): time:      9.151979s, rx: 0k/s, tx: 0k/s
[    10.136074s]  INFO(libboard_zynq::eth): eth: got Link { speed: S1000, duplex: Full }
[    10.143862s] DEBUG(libboard_zynq::eth): Eth TX clock for 125000000: 999999990 / 1 / 8 = 124999998
[    10.158977s]  INFO(experiments): time:     10.158976s, rx: 0k/s, tx: 0k/s
[    11.165975s]  INFO(experiments): time:     11.165973s, rx: 0k/s, tx: 0k/s
[    12.172975s]  INFO(experiments): time:     12.172974s, rx: 0k/s, tx: 0k/s
...
## Summary - add `start_with_interrupt` for GlobalTimer - refactor mpcore - fix `comp_enable` typo - combine `icdicer` register into an array to make register control easier - add support for disabling individual interrupt - add GlobalTimer interrupt test to experiment for core0 - tested on kasli_soc - Compilation check - `nix build <variant>` for szl, coraz7-experiments, zc706-experiments and kasli_soc-experiments. All compiled without warning ## New experiment log ```bash Zynq experiments [ 48.742291s] INFO(experiments): Boot mode: SdCard [ 48.747071s] INFO(experiments): Setup clock sources... [ 48.752277s] DEBUG(libboard_zynq::clocks::source): Set ARM_PLL to 1600000000 Hz [ 13.205717s] DEBUG(libboard_zynq::clocks::source): Set IO_PLL to 1000000000 Hz [ 13.215440s] INFO(experiments): PLLs set up [ 13.219747s] INFO(experiments): CPU Clocks: 799999992/399999996/266666664/133333332 [ 0.000000s] DEBUG(libboard_zynq::clocks::source): Set DDR_PLL to 1066666666 Hz [ 0.007308s] DEBUG(libboard_zynq::ddr): DDR 3x/2x clocks: 533333328/355555552 [ 0.014483s] DEBUG(libboard_zynq::ddr): DDR DCI clock: 10062892 Hz (divisors=2*53) [ 0.024392s] INFO(libboard_zynq::ddr): memtest phase 0 (status: Normal) 511 MB Ok [ 1.374867s] INFO(libboard_zynq::ddr): memtest phase 1 (status: Normal) 511 MB Ok [ 2.896332s] INFO(libboard_zynq::ddr): memtest phase 2 (status: Normal) 511 MB Ok [ 4.416859s] INFO(libboard_zynq::ddr): memtest phase 3 (status: Normal) 511 MB Ok [ 5.937361s] INFO(experiments): Enable GlobalTimer interrupt on core0 GlobalTimer interrupting core0... GlobalTimer interrupting core0... [ 6.046825s] INFO(experiments): Disable GlobalTimer interrupt [ 6.052640s] INFO(experiments): Send software interrupt to core0 Interrupting core0... [ 6.060626s] INFO(experiments): Core0 returned from interrupt Hello from core1! Hello from core1! 0 -> 0 Hello from core1! 1 -> 1 Hello from core1! 2 -> 4 Hello from core1! 3 -> 9 Hello from core1! 4 -> 16 Hello from core1! 5 -> 25 Hello from core1! 6 -> 36 Hello from core1! 7 -> 49 Hello from core1! 8 -> 64 Hello from core1! 9 -> 81 [ 6.090383s] DEBUG(libboard_zynq::eth): Eth TX clock for 125000000: 999999990 / 1 / 8 = 124999998 Eth on [ 7.137988s] INFO(experiments): time: 7.137986s, rx: 0k/s, tx: 0k/s [ 8.144985s] INFO(experiments): time: 8.144983s, rx: 0k/s, tx: 0k/s [ 9.151981s] INFO(experiments): time: 9.151979s, rx: 0k/s, tx: 0k/s [ 10.136074s] INFO(libboard_zynq::eth): eth: got Link { speed: S1000, duplex: Full } [ 10.143862s] DEBUG(libboard_zynq::eth): Eth TX clock for 125000000: 999999990 / 1 / 8 = 124999998 [ 10.158977s] INFO(experiments): time: 10.158976s, rx: 0k/s, tx: 0k/s [ 11.165975s] INFO(experiments): time: 11.165973s, rx: 0k/s, tx: 0k/s [ 12.172975s] INFO(experiments): time: 12.172974s, rx: 0k/s, tx: 0k/s ... ```
morgan added 3 commits 2023-12-14 13:06:08 +08:00
1b714a8ca0 GlobalTimer: add timer IRQ to experiment
gic: add disable individual interrupt support
mpcore: refactor icdicer registers as array
main: start timer with interrupt and add IRQ
mwojcik reviewed 2023-12-14 17:21:05 +08:00
@ -43,1 +87,4 @@
);
}
fn get_prescalar() -> u32 {
Owner

prescaler

``prescaler``
Owner

Why would WRPLL need the timer?

Why would WRPLL need the timer?
Author
Owner

Why would WRPLL need the timer?

It's for WRPLL interrupt service routine, so the main&helper PLL will run periodically using the timer interrupt instead of using timer.delay_us() and blocking the core.

> Why would WRPLL need the timer? It's for WRPLL interrupt service routine, so the main&helper PLL will run periodically using the timer interrupt instead of using `timer.delay_us()` and blocking the core.
morgan added 1 commit 2023-12-15 10:15:38 +08:00
Owner

Does it have to run precisely with exact intervals? You can have a thread with timer.countdown() and delay(..).await that yields and does not block the core. Although if the code PLL code would be short, doing it with interrupts seems like a good idea, since it would be less overhead than threads.

Does it have to run precisely with exact intervals? You can have a thread with ``timer.countdown()`` and ``delay(..).await`` that yields and does not block the core. Although if the code PLL code would be short, doing it with interrupts seems like a good idea, since it would be less overhead than threads.
morgan closed this pull request 2023-12-15 10:39:31 +08:00
Author
Owner

Misclicked closed for cancel comments

Misclicked closed for cancel comments
morgan reopened this pull request 2023-12-15 10:40:17 +08:00
Owner

Does it have to run precisely with exact intervals?

AFAICT yes. The WRPLL loop would run in the background using the interrupt service routine.

the main&helper PLL will run periodically using the timer interrupt

Shouldn't they be triggered instead from "DDMTD measurement completed" interrupts from the gateware?

> Does it have to run precisely with exact intervals? AFAICT yes. The WRPLL loop would run in the background using the interrupt service routine. > the main&helper PLL will run periodically using the timer interrupt Shouldn't they be triggered instead from "DDMTD measurement completed" interrupts from the gateware?
Author
Owner

Shouldn't they be triggered instead from "DDMTD measurement completed" interrupts from the gateware?

Yes that will actually improve the tracking performance for the PLLs, closing.

> Shouldn't they be triggered instead from "DDMTD measurement completed" interrupts from the gateware? Yes that will actually improve the tracking performance for the PLLs, closing.
morgan closed this pull request 2023-12-15 12:53:29 +08:00

Pull request closed

Sign in to join this conversation.
No reviewers
No Label
No Milestone
No Assignees
3 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: M-Labs/zynq-rs#108
No description provided.