Таймеры в BCM2835/BCM2836

Только технические вопросы по ЯОС и MINOS. Терминология и прочее - в других форумах.
Ответить
БудДен
Сообщения: 2839
Зарегистрирован: 07.10.18 14:01

Таймеры в BCM2835/BCM2836

Сообщение БудДен » 14.10.22 15:50

Есть system timer, со смещением 0x3000, описан в BCM2835-ARM-Peripherals.pdf, гла 12, system timer registers.
Однако прерывания где?

TimerIRQ не используется в сборке Zynq, а используется
только PrivateTimerIRQ* = 29

Что такое PrivateTimer? Он упомянут где-то, но сейчас не ищется в локальных ресурсах, включая документацию и исходники. Гуглим.

https://github.com/umanovskis/baremetal ... eduling.md
A Cortex-A9 MPCore CPU provides a global timer and private timers. There's one private timer per core. The global timer is constantly counting up, even with the CPU paused in debug mode. The per-core private timers count down from some starting value to zero, sending an interrupt when zero is reached. It's possible to use either timer for scheduling, but the typical solution is to use the private timer. It's somewhat easier to handle due to being 32 bits wide (the global timer is 64 bits) and due to stopping when the CPU is stopped.
Всё классно, но у нас версия A7. Лезем в документ BCM2836-Cortex-A7-MPcore-Processor-Reference-Manual.pdf

Вот что там можно найти:
Private Peripheral Interrupts
A PPI is an interrupt generated by a peripheral that is specific to a single
processor. There are seven PPIs for each CPU interface:
Legacy nFIQ signal (PPI0)
When the GIC interrupt bypass is in effect, such as after reset, the
external nFIQ signal bypasses the interrupt distributor logic and
directly drives the interrupt request to the corresponding processor.
When a processor uses the GIC rather than the external nFIQ signal,
by enabling its own CPU interface, the nFIQ signal is treated like
other interrupt lines and uses ID28. The interrupt is active-LOW
level-sensitive.
Secure Physical Timer event (PPI1)
This is the event generated from the Secure Physical Timer and uses
ID29. The interrupt is level-sensitive.
Non-secure Physical Timer event (PPI2)
This is the event generated from the Non-secure Physical Timer and
uses ID30. The interrupt is level-sensitive.
Legacy nIRQ signal (PPI3)
When the GIC interrupt bypass is in effect, such as after reset, the
external nIRQ signal bypasses the interrupt distributor logic and
directly drives the interrupt request to the corresponding processor.
When a processor uses the GIC rather than the external nIRQ signal,
by enabling its own CPU interface, the nIRQ signal is treated like
other interrupt lines and uses ID31. The interrupt is active-LOW
level-sensitive.
Virtual Timer event (PPI4)
This is the event generated from the Virtual Timer and uses ID27. The
interrupt is level-sensitive.
Hypervisor Timer event (PPI5)
This is the event generated from the Physical Timer in Hypervisor
mode and uses ID26. The interrupt is level-sensitive.
А также:
The Generic Timer can schedule events and trigger interrupts based on an incrementing counter
value. It provides:
• Generation of timer events as interrupt outputs.
• Generation of event streams.
• Support for Virtualization Extensions.
The Cortex-A7 MPCore Timer is compliant with the ARM Architecture Reference Manual.
This chapter only describes features that are specific to the Cortex-A7 MPCore implementation

The Cortex-A7 MPCore processor provides a set of four timers for each processor in the cluster.
• Physical Timer for use in Secure and Non-secure PL1 modes. The registers for the
Physical Timer are banked to provide Secure and Non-secure copies.
• Virtual Timer for use in Non-secure PL1 modes.
• Physical Timer for use in Hyp mode.
The counter value is distributed to the processor with a synchronous binary encoded 64-bit bus,
CNTVALUEB[63:0]

БудДен
Сообщения: 2839
Зарегистрирован: 07.10.18 14:01

Re: Таймеры в BCM2835/BCM2836

Сообщение БудДен » 14.10.22 16:00

очевидно, что речь всё же идёт о разных таймерах. О. нашлось мистически, bcm2836-peripherals.pdf
4.11 Local timer
The code has a single local timer which can generate interrupts. The local timer ALWAYS gets its timing
pulses from the Crystal clock. You get a 'timing pulse' every clock EDGE. Thus a 19.2 MHz crystal gives
38.4 M pulses/second.
Но похоже, это не тот, т.к. этот один, а частных - много. Где же они, гады?

БудДен
Сообщения: 2839
Зарегистрирован: 07.10.18 14:01

Re: Таймеры в BCM2835/BCM2836

Сообщение БудДен » 14.10.22 16:07

Похоже, не избежать чтения e ARM Generic Interrupt Controller Architecture Specification

БудДен
Сообщения: 2839
Зарегистрирован: 07.10.18 14:01

Re: Таймеры в BCM2835/BCM2836

Сообщение БудДен » 15.10.22 20:38

edge activated - как я понял, прерывание повисает при наступлении события (переключении уровня) и само не исчезает
level activated - запрос на прерывание исчезает, когда уровень сигнала падает. Т.е. не успели обработать - вопрос снят.

БудДен
Сообщения: 2839
Зарегистрирован: 07.10.18 14:01

Re: Таймеры в BCM2835/BCM2836

Сообщение БудДен » 17.10.22 10:10

Вот ещё тема, где утверждается, что BCM2835 можно использовать таймеры на ядро, но с кодом не очень. Также кто-то пишет, что 2836 отличается. Впрочем, это можно попробовать посмотреть в исходниках QEMU.

https://forums.raspberrypi.com/viewtopi ... 1&p=922616
I have been using the Local Timer as spec'ed in the BCM2836 doc "ARM Quad A7 core — Gert van Loo, 18 August 2014" for a countdown timer ... timer control is at 0x40000034, and I can get periodic interrupts just fine. My question is how can I get multiple timers, one on each of the four cores? Or at least two different ones if not four different ones.

Thank you!
Bruce
И ответ:
Hi Bruce, The QA7 document does actually contain most of the info you need to get multiple timers per core, it just isn't always clear unless you also know about some other ARM specific info.

The Local Timer you have been using at 0x40000034 is a single timer only which seems to be implemented as part of the ARM control logic in the BCM2836, elsewhere in that document you will find references to CNTVIRQ / CNTHPIRQ / CNTPNSIRQ / CNTPSIRQ.

These are referring to the Generic Timer that is internal to each of the 4 Cortex A7s and are documented in the ARM Architecture Reference Manual itself, you need the ARMv7-A / ARMv7-M edition which can be found online if you search.

The registers at 0x40000040 to 0x4000004C allow you to enable IRQ/FIQ for each of the 4 timers on each of the 4 cores and interrupts are reported in the registers at 0x40000060 to 0x4000006C.

To actually set or read the timer counts and enable the timers you need to use MCR/MRC instructions to manipulate the values in the ARM control registers instead.

Of the 4 timers CNTV (Virtual Timer) , CNTHP (Hypervisor Timer), CNTPNS (Physical Non Secure Timer) and CNTPS (Physical Secure Timer) you can use at least 2 per core.

The non secure/secure versions of the physical timer are only available from the appropriate mode (Secure/Non Secure) so you can use one or the other, the virtual timer is usable in most cases and the hypervisor timer appears to be only usable from hypervisor mode.

Ответить