Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 8 May 2024 08:36:53 +0200
From:      John Hay <john@sanren.ac.za>
To:        Poul-Henning Kamp <phk@phk.freebsd.dk>
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: FreeBSD driver for the OCP TAP Time Card
Message-ID:  <CAGv8uaoQn_XMB4=4%2B0ZLvyDd9BaZO=1KC1xDvnOpWLVKXDvoXw@mail.gmail.com>
In-Reply-To: <202405080535.4485ZFN9066673@critter.freebsd.dk>
References:  <CAGv8uar=CmAXowLUS1H2hEHk3OPJPifgXSy3Ru9VodRcoy4yPA@mail.gmail.com> <202405080535.4485ZFN9066673@critter.freebsd.dk>

next in thread | previous in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
Hi Poul-Henning,

On Wed, 8 May 2024 at 07:35, Poul-Henning Kamp <phk@phk.freebsd.dk> wrote:

> --------
> John Hay writes:
>
> > I have been working on a FreeBSD driver for the Open Compute Project
> (OCP)
> > Time Appliance Project (TAP) Time Card. The card consists of three main
> > parts, a clock module, a GNSS module and a FPGA module. The firmware for
> > the FPGA implements a counter that is synchronized to TAI using the GNSS
> > module and the clock module. The counter is implemented as two 32-bit
> > registers, seconds and nanoseconds, like struct timespec, and make that
> > available on the pci-e bus.
>
> That is /precisely/ the kind of hardware timecounters were designed for :-)
>

True, it did make it a lot easier. :-) Working close to the nanosecond does
seem to push things close to the limits though. :-)

There are a few things I wish could be handled differently. Maybe there are
ways, and I just did not find them. :-)

One is that you cannot just feed timecounters with a timespec value. It
assumes the hardware counter is in binary, while in this case, the
nanoseconds rolls over at 1 second, so for every tc_get_timecount(), you
have to multiply the seconds register value by 10^9 and then add the
nanosecond register value. Not a big deal and reading the registers over
the pci-e bus is the slowest part by far.

The other is that the conversion from the above value to bintime and later
back to what is used elsewhere, seems to lose a little precision. The
comments in sys/kern/kern_tc.c also note that.

In the pps code, I wished that one could provide a timestamp with
pps_capture(). It uses the time at which it handled the interrupt. The card
latch the counter values when the pps happens, so it knows the correct
time. Currently I hack around it by twiddling sc->sc_pps_state.capcount
directly.

Regards

John

[-- Attachment #2 --]
<div dir="ltr"><div dir="ltr">Hi Poul-Henning,<br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, 8 May 2024 at 07:35, Poul-Henning Kamp &lt;<a href="mailto:phk@phk.freebsd.dk">phk@phk.freebsd.dk</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">--------<br>
John Hay writes:<br>
<br>
&gt; I have been working on a FreeBSD driver for the Open Compute Project (OCP)<br>
&gt; Time Appliance Project (TAP) Time Card. The card consists of three main<br>
&gt; parts, a clock module, a GNSS module and a FPGA module. The firmware for<br>
&gt; the FPGA implements a counter that is synchronized to TAI using the GNSS<br>
&gt; module and the clock module. The counter is implemented as two 32-bit<br>
&gt; registers, seconds and nanoseconds, like struct timespec, and make that<br>
&gt; available on the pci-e bus.<br>
<br>
That is /precisely/ the kind of hardware timecounters were designed for :-)<br></blockquote><div><br></div><div>True, it did make it a lot easier. :-) Working close to the nanosecond does seem to push things close to the limits though. :-)<br></div><div><br></div><div>There are a few things I wish could be handled differently. Maybe there are ways, and I just did not find them. :-)<br></div><div><br></div><div>One is that you cannot just feed timecounters with a timespec value. It assumes the hardware counter is in binary, while in this case, the nanoseconds rolls over at 1 second, so for every tc_get_timecount(), you have to multiply the seconds register value by 10^9 and then add the nanosecond register value. Not a big deal and reading the registers over the pci-e bus is the slowest part by far.<br></div><div><br></div><div>The other is that the conversion from the above value to bintime and later back to what is used elsewhere, seems to lose a little precision. The comments in sys/kern/kern_tc.c also note that. <br></div><div><br></div><div>In the pps code, I wished that one could provide a timestamp with pps_capture(). It uses the time at which it handled the interrupt. The card latch the counter values when the pps happens, so it knows the correct time. Currently I hack around it by twiddling sc-&gt;sc_pps_state.capcount directly.</div></div><div class="gmail_quote"><br></div><div class="gmail_quote">Regards</div><div class="gmail_quote"><br></div><div class="gmail_quote">John<br></div></div>

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAGv8uaoQn_XMB4=4%2B0ZLvyDd9BaZO=1KC1xDvnOpWLVKXDvoXw>