HPET wrongly configured for 64-bit periodic mode

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
limp
Member
Member
Posts: 90
Joined: Fri Jun 12, 2009 7:18 am

HPET wrongly configured for 64-bit periodic mode

Post by limp »

Hi all,

I have a problem with my HPET driver and specifically when I set the timer to operate in “64-bit periodic mode”. In this case, I am not getting any interrupts and that’s because the high nibble of the T0 Comparator value register (which should be 0 according to the value I am writing) gets set to 0xFFFFFFFF. All the other registers (low nibble of T0 Comparator and low and high nibble of T0 main counter) have the expected values.

This problem doesn’t appear when I setup the timer to “64-bit one-shot mode”. Also, when I configure the timer for “32-bit mode” operation, the above problem doesn’t appear neither on “periodic” or “one-shot” modes.

I do 32-bit operations (reads/writes) in the driver and something weird I noticed is the following: If (for setting 64-bit periodic mode) I firstly write the high nibble of the comparator register and then the low nibble, I get 0 in the high-nibble and 0xFFFFFFFF in the low-nibble. If I do the writes the other way around (low nibble first and then high nibble), I get my “counter” value in the low-nibble and 0xFFFFFFFF in the high-nibble of the comparator.

Code: Select all

                          |  high-nibble |   low-nibble  |
----------------------------------------------------------
High nibble write first	|       0      |   0xFFFFFFFF  |
----------------------------------------------------------
Low nibble write first    |  0xFFFFFFFF  |  Count value  |
----------------------------------------------------------
Do you guys happen to have any idea of what could be wrong?

Thanks in advance.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: HPET wrongly configured for 64-bit periodic mode

Post by Combuster »

I haven't done anything with HPETs prior, but based on the symptoms it seems that it expects a single 64-bit write and not a 32-bit write, let alone two. The manual should have the proper guidelines on register sizes.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
xenos
Member
Member
Posts: 1121
Joined: Thu Aug 11, 2005 11:00 pm
Libera.chat IRC: xenos1984
Location: Tartu, Estonia
Contact:

Re: HPET wrongly configured for 64-bit periodic mode

Post by xenos »

Actually the HPET Spec says:
Software can access the various bytes in this register using 32-bit or 64-bit accesses. 32-bit accesses can be done to offset 1x8h or 1xCh. 64-bit accesses can be done to 1x8h. 32-bit accesses must not be done to offsets 1x9h, 1xAh, 1xBh, 1xDh, 1xEh, or 1xFh.
So in principle two consecutive 32-bit accesses should be fine.

However, ths same document states that in periodic mode:
After the main counter equals the value in this register, the value in this register is increased by the value last written to the register.
I'm not sure what this "value last written to the register" is in case of two 32-bit transfers.
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: HPET wrongly configured for 64-bit periodic mode

Post by Brendan »

Hi,
XenOS wrote:However, ths same document states that in periodic mode:
After the main counter equals the value in this register, the value in this register is increased by the value last written to the register.
I'm not sure what this "value last written to the register" is in case of two 32-bit transfers.
To me it sounds like you should be setting the "Tn_32MODE_CNF" flag (and testing if it's writeable or not). You'd have to support "32-bit mode only" for hardware that doesn't have a 64-bit main counter, so it's not much extra work to set one bit. For periodic mode with "32-bit only" you'd be able to reach frequencies much slower than 1 Hz anyway (e.g. as slow as "429 seconds between IRQs" or 0.0023 Hz if the main counter is running at 10 Mhz); and if you really needed slower frequencies you could ignore every second (or third, or "Nth") IRQ in software.

However; as far as I can tell, it should be possible for 32-bit code (on Pentium or later) to stop the main counter and then use "cmpxchg8b" to do an atomic 64-bit write. If you don't want to stop the counter, then it might still be possible to use "cmpxchg8b" in a loop if the CPU is fast enough.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
limp
Member
Member
Posts: 90
Joined: Fri Jun 12, 2009 7:18 am

Re: HPET wrongly configured for 64-bit periodic mode

Post by limp »

Hi guys,
Brendan wrote: To me it sounds like you should be setting the "Tn_32MODE_CNF" flag (and testing if it's writeable or not). You'd have to support "32-bit mode only" for hardware that doesn't have a 64-bit main counter, so it's not much extra work to set one bit.
I've verified by all means that the target's HPET is 64-bit. The "Tn_32MODE_CNF" flag is writable and the "Tn_SIZE_CAP" is 1 (indicating a 64-bit timer).

Since my initial post, I've been doing some more testing and I noticed that if I initially force HPET to operate in 32-bit mode (i.e. set the "Tn_32MODE_CNF" flag) and then set it to 64-bit mode (by un-setting the "Tn_32MODE_CNF" flag), then I don't get 0xFFFFFFF in the high nibble of the comparator and everything works fine!!!

I've put printfs and I checked that in any case (1: forcing the timer to 32-bit and then setting it 64-bit and 2: setting the timer to 64-bit straight away), the low-nibble of the "Timer N Configuration" register gets the same value (which is 0x38 in my case) so, I can't really understand why I need to force it to 32-bit mode first for making it work.

Does anyone operate HPET in 64-bit mode and have a similar experience?

Also, an implementation question is this: Do you think that it could be a problem because i config one flag of the "Timer N Configuration" register at a time instead of setting a temporary variable and writing the final result of it into the register once in the end?

Kind regards.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: HPET wrongly configured for 64-bit periodic mode

Post by Combuster »

Do you think that it could be a problem because i config one flag of the "Timer N Configuration" register at a time instead of setting a temporary variable and writing the final result of it into the register once in the end?
That depends on whether or not you are familiar with "volatile"?
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
limp
Member
Member
Posts: 90
Joined: Fri Jun 12, 2009 7:18 am

Re: HPET wrongly configured for 64-bit periodic mode

Post by limp »

Hi,
Combuster wrote:
Do you think that it could be a problem because i config one flag of the "Timer N Configuration" register at a time instead of setting a temporary variable and writing the final result of it into the register once in the end?
That depends on whether or not you are familiar with "volatile"?
I am quite familiar with "volatile" but I don't quite see how this relates to my question. Could you be a bit more specific please?

Kind regards.
Post Reply