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
--000000000000efee4d0617eb87d5
Content-Type: text/plain; charset="UTF-8"

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

--000000000000efee4d0617eb87d5
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div dir=3D"ltr">Hi Poul-Henning,<br></div><br><div class=
=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_attr">On Wed, 8 May 2024 a=
t 07:35, Poul-Henning Kamp &lt;<a href=3D"mailto:phk@phk.freebsd.dk">phk@ph=
k.freebsd.dk</a>&gt; wrote:<br></div><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);paddin=
g-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 mai=
n<br>
&gt; parts, a clock module, a GNSS module and a FPGA module. The firmware f=
or<br>
&gt; the FPGA implements a counter that is synchronized to TAI using the GN=
SS<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 tha=
t<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 limi=
ts though. :-)<br></div><div><br></div><div>There are a few things I wish c=
ould 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 tim=
ecounters with a timespec value. It assumes the hardware counter is in bina=
ry, while in this case, the nanoseconds rolls over at 1 second, so for ever=
y 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 t=
he 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 bint=
ime and later back to what is used elsewhere, seems to lose a little precis=
ion. 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 wit=
h pps_capture(). It uses the time at which it handled the interrupt. The ca=
rd latch the counter values when the pps happens, so it knows the correct t=
ime. Currently I hack around it by twiddling sc-&gt;sc_pps_state.capcount d=
irectly.</div></div><div class=3D"gmail_quote"><br></div><div class=3D"gmai=
l_quote">Regards</div><div class=3D"gmail_quote"><br></div><div class=3D"gm=
ail_quote">John<br></div></div>

--000000000000efee4d0617eb87d5--



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