Bug 119574 - [i386] 7.0-RC1 times out in calibrate_clocks() [regression]
Summary: [i386] 7.0-RC1 times out in calibrate_clocks() [regression]
Status: Closed Overcome By Events
Alias: None
Product: Base System
Classification: Unclassified
Component: i386 (show other bugs)
Version: Unspecified
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-i386 (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-01-11 21:10 UTC by Oliver B. Warzecha
Modified: 2019-01-07 05:08 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Oliver B. Warzecha 2008-01-11 21:10:01 UTC
The 7.0-RC1 GENERIC kernel fails to recognize that the seconds counter
changes during the loops in calibrate_clocks() in sys/i386/isa/clocks.c

The same machine passes this routine quickly with 6.2-RELEASE-p8. It
is a 200 MHz AMD K6 on an ASUS P55T2P4S board.

Through generous use of debugging printf()'s while searching, I could
limit the possible causes to this lines:
        timeout = 100000000;

        /* Read the mc146818A seconds counter. */
        for (;;) {
                if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) {
                        sec = rtcin(RTC_SEC);
                        break;
                }
                if (--timeout == 0)
                        goto fail;
        }
//        printf("seconds counter read ... \n");
        /* Wait for the mC146818A seconds counter to change. */
        start_sec = sec;
        for (;;) {
                if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) {
                        sec = rtcin(RTC_SEC);
                        if (sec != start_sec)
                                break;
                }
                if (--timeout == 0)
                        goto fail;
        }
//        printf("seconds counter changed ... \n");
(my debugging printf()s commented out with C++ comments)
The first output "seconds counter read" gets printed very fast.
After that the machine counts back from 0 to 0 and after some minutes
he falls out of the loop and "seconds counter changed" gets never
printed.

As I noticed that rtcin() was reworked during the change to 7.0,
(http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/i386/isa/clock.c.diff?r1=1.222.2.2;r2=1.239.2.1;f=h)
 it occurred to me that perhaps there might be some condition
in the new code.

As I said, on a 6.2-RELEASE-p8 kernel it all goes smoothly, I just
checked with boot -v:
Calibrating clock(s) ... i8254 clock: 1193296 Hz
CLK_USE_I8254_CALIBRATION not specified - using default frequency
Timecounter "i8254" frequency 1193182 Hz quality 0

It does *not* say "failed, using default i8254 clock [...]" which
would indicate the "fault" label.

Fix: 

One possible workaround would be to reset the timeout variable
to a more sane value, for the first loop it gets set to
100000000. But then this loop seems to work okay, so I have
no idea what a sane value would be. At least it would fail
fast.

For a complete fix I have no idea than to revert to the 6.2-code.
But I think, this may be out of the question.
How-To-Repeat: boot 7.0-RC1 GENERIC on the hardware mentioned above (tested it on 
one other machine with "no ACPI" from the the boot CD, but that
 one booted fast and recognized the timer)
Comment 1 Bruce Evans freebsd_committer freebsd_triage 2008-01-13 13:11:34 UTC
On Fri, 11 Jan 2008, Oliver B. Warzecha wrote:

>> Description:
> The 7.0-RC1 GENERIC kernel fails to recognize that the seconds counter
> changes during the loops in calibrate_clocks() in sys/i386/isa/clocks.c
>
> The same machine passes this routine quickly with 6.2-RELEASE-p8. It
> is a 200 MHz AMD K6 on an ASUS P55T2P4S board.

Oops.

> Through generous use of debugging printf()'s while searching, I could
> limit the possible causes to this lines:
> [... moved this later]

> As I noticed that rtcin() was reworked during the change to 7.0,
> (http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/i386/isa/clock.c.diff?r1=1.222.2.2;r2=1.239.2.1;f=h)
> it occurred to me that perhaps there might be some condition
> in the new code.

Probably.  I wrote both.  Apparently I optimized rtcin() too much.
Try adding some delays to it, and/or more debugging code.  For debugging
code, just read the RTC index register and verify that it is set to
the memory value that is supposed to track it.  Check after writing
to it and when the write is avoided because it already has the desired
value according to the memory value.

> As I said, on a 6.2-RELEASE-p8 kernel it all goes smoothly, I just
> checked with boot -v:
> Calibrating clock(s) ... i8254 clock: 1193296 Hz
> CLK_USE_I8254_CALIBRATION not specified - using default frequency
> Timecounter "i8254" frequency 1193182 Hz quality 0
>
> It does *not* say "failed, using default i8254 clock [...]" which
> would indicate the "fault" label.

The calibration isn't really used unless you configure
CLK_USE_I8254_CALIBRATION.  Otherwise, it is just a sanity check. I
stopped using this configuration a few years ago when I switched to a
more dynamic calibration scheme.

>> Fix:
> One possible workaround would be to reset the timeout variable
> to a more sane value, for the first loop it gets set to
> 100000000. But then this loop seems to work okay, so I have
> no idea what a sane value would be. At least it would fail
> fast.

100 million is supposed to be 100 seconds with a large safety margin.
This depends on rtcin() taking at least 1 usec by doing slow
hardware accesses.  But 100 seconds is too long and rtcin() normally
takes much longer than 1us.  I reduced it to 1 million locally.  You
should reduce it to debug this (so that it times out after < 10
seconds).

>        timeout = 100000000;
>
>        /* Read the mc146818A seconds counter. */
>        for (;;) {
>                if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) {
>                        sec = rtcin(RTC_SEC);
>                        break;
>                }
>                if (--timeout == 0)
>                        goto fail;
>        }
> //        printf("seconds counter read ... \n");

The optimization might break this by going too fast -- it now reads the
status register as fast as possible, where before it had lots of delays.
It still has the delays (supposed to be done more carefully than before
when switching to reading the seconds register, so I would expect the
read of the seconds register to be as correct as before, but it apparently
isn't.

>        /* Wait for the mC146818A seconds counter to change. */
>        start_sec = sec;
>        for (;;) {
>                if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) {
>                        sec = rtcin(RTC_SEC);
>                        if (sec != start_sec)
>                                break;
>                }
>                if (--timeout == 0)
>                        goto fail;
>        }
> //        printf("seconds counter changed ... \n");
> (my debugging printf()s commented out with C++ comments)

This should behaves similarly.

> The first output "seconds counter read" gets printed very fast.

Do you think it gets printed too fast?  It should take 1/2 second on
average to reach the next seconds boundary, then another second to
calibrate.  Configure CLK_CALIBRATION_LOOP and boot with -v to see
the calibration repeated precisely every second if it is working.

> After that the machine counts back from 0 to 0 and after some minutes
> he falls out of the loop and "seconds counter changed" gets never
> printed.

You could also try watching the RTCSA_TUP bit.  This should change every
second and stay set for a while.  Some logic would be required to limit
printfs to 1 per change.  This bit alone could be used to detect seconds
boundaries.

I just noticed that I reduced the accuracy of the calibration by adding
delays to rtcin().  I had the delays commented out in my version but put
them back when I optimized the usual case of rtcin() being called from
the RTC interrupt handler (the index register is normally constant then).
The (relative) accuracy is limited the time that it takes to read the
seconds register and the time it takes to read the I8254, and though
the code is arranged so that the inaccuracy is much less than the sum
of these times, increasing the times doesn't help.  There is probably
also more jitter from branch misprediction in rtcin() when switching
indexes.  So watching only the RTCSA_TUP bit would be good for accuracy
too.  The seconds register could be read in non-time-critical code
after reading all the other registers as a sanity check (check that it
is incremented by 1; the current code only checks that it changes).

Bruce
Comment 2 Oliver B. Warzecha 2008-02-06 11:37:21 UTC
Okay, it took some time, one reason the machine in question being
used as my router, which reduces research options when test
booting kernels...

On Mon, Jan 14, 2008 at 12:11:34AM +1100, Bruce Evans wrote:
> On Fri, 11 Jan 2008, Oliver B. Warzecha wrote:
> 
> >As I noticed that rtcin() was reworked during the change to 7.0,
> >(http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/i386/isa/clock.c.diff?r1=1.222.2.2;r2=1.239.2.1;f=h)
> >it occurred to me that perhaps there might be some condition
> >in the new code.
> 
> Probably.  I wrote both.  Apparently I optimized rtcin() too much.
> Try adding some delays to it, and/or more debugging code.  For debugging
> code, just read the RTC index register and verify that it is set to
> the memory value that is supposed to track it.  Check after writing
> to it and when the write is avoided because it already has the desired
> value according to the memory value.

I came relatively fast to the conclusion that reading the register
leads nowhere, it seems to be a write-only register that never
yields the value just written to it.

> >
> >       /* Read the mc146818A seconds counter. */
> >       for (;;) {
> >               if (!(rtcin(RTC_STATUSA) & RTCSA_TUP)) {
> >                       sec = rtcin(RTC_SEC);
> >                       break;
> >               }
> >               if (--timeout == 0)
> >                       goto fail;
> >       }
> >//        printf("seconds counter read ... \n");
> 
> The optimization might break this by going too fast -- it now reads the
> status register as fast as possible, where before it had lots of delays.
> It still has the delays (supposed to be done more carefully than before
> when switching to reading the seconds register, so I would expect the
> read of the seconds register to be as correct as before, but it apparently
> isn't.

I have found at least one design - one of these compact PC on a PCI card
designs:
http://www.pt.com/Manuals_Legacy/ZT_5510_Manual_PTI.pdf -

where it is explicitely mentioned in the documentation that for repeated
access to the same register in the RTC you have to set the address
register again. This card is also based on the HX chipset, maybe
this limitation was lifted in newer designs. Maybe accesses on newer
systems are fast enough that any capacitors in the circuit are
refreshed, whatever, this is pure speculation. It is tough to
find some definitive documentation on the net about this issue.

Anyway, at least for this specific case, it seems that only the
original way of clock access was the right one, I am afraid.

For what it's worth, I just checked the linux sources, it's also
straight "write address register, then read/write data" there.

It would be nice to have some definitive documentation on that
case, but I have no idea right now.

OBW
(rest snipped, as it does not apply as long as the register is
not read correctly)
Comment 3 Oliver B. Warzecha 2008-02-06 15:55:14 UTC
Addon to my last mail, as I just discovered the i440BX-Specs, just
2 clicks away from one of the pages where I last searched for info.
They are downloadable from
http://www.intel.com/design/intarch/datashts/290562.htm

On page 84, there is specified that the RTC index register
is write only (as I found out in practical testing :-). And it
is also described as a latch register, which makes the current
code "working by pure chance", as it's implementation dependent
which bus noise happens on the other side of the gate. (If I
didn't get the meaning of "latch" in this case totally wrong)

regards,
OBW
Comment 4 Bruce Evans freebsd_committer freebsd_triage 2008-02-08 12:30:12 UTC
On Wed, 6 Feb 2008, Oliver B. Warzecha wrote:

> Addon to my last mail, as I just discovered the i440BX-Specs, just
> 2 clicks away from one of the pages where I last searched for info.
> They are downloadable from
> http://www.intel.com/design/intarch/datashts/290562.htm

I found I even have the 1998 version of that locally.

> On page 84, there is specified that the RTC index register
> is write only (as I found out in practical testing :-). And it

I think it actually says that the register is more or less readable
"Reads ... flow through to the ISA bus, but no RT... will be generated".
It says that the register is traditionally write-only.  However, ISTR
successfully reading this register from debuggers on 5-10 machines
over the last 15-20 years.

Van Gilluwe's book published in 1993 or 1994 says that the index
register is write-only and complains that h/w designers keep making
the mistake of write-only registers.  Van Gilluwe gives mainly access
methods that take not just 2, but 3 ISA accesses to the RTC ports, and
2 I/O delays of 1-16 usec to ensure slowing things down further.  The
extra RTC access is to turn the NMI disable bit in the index register
back off after turning it on together with setting the index.  It
doesn't bother to preserve either the old or the new index, and always
leaves the index set at 0.  This NMI bit is more portable than I thought
-- the Intel data sheet documents it.  This much care with NMIs may
be required if NMIs actually happen.  FreeBSD is generally careless
with NMIs, and doesn't touch the NMI bit in its RTC access functions
except to blindly clear it.

> is also described as a latch register, which makes the current
> code "working by pure chance", as it's implementation dependent
> which bus noise happens on the other side of the gate. (If I
> didn't get the meaning of "latch" in this case totally wrong)

The wording is: "[Index register]: latched by the real time clock...";
[Data register]: Data written to standard RAM bank address selected
by RTC Index...".  These descriptions conflict a bit.  The first one
doesn't quite say that the data value at the time of the write to the
index register is latched to be read by any later read of the data
register, and the second one doesn't quite say that the index register
is just a select (latched at the time of read of the data register)
for the data.  The first behaviour can be tested for (try to latch the
current seconds value and read the data register several seconds later
and see if you got the old value (*)), but we know that it doesn't work
like that on more machines, else my change would break most machines
(RTC interrupts would be broken if reading the data register didn't
give current data).

I think you just have unusual hardware, else more machines would have
broken.  However, I fear there is a problem somewhere, since RTC
interrupts broke a couple of times last week on my main machine (with
a VIA VT8237(??) bridge).  It's surprising how well FreeBSD works with
the statistics clock stopped.  I haven't looked at your other hardware
reference yet.

(*) A quick test using ddb on my hardware shows that reading the data
register for the seconds register gives its current value, not the
value at the time of the write of the seconds register index (0) to
the index register.  Then subsequent reads of the data register
with no intervening write to the index register keep returning the
current seconds register.  I tested using ddb, and trust ddb not to
access the RTC in normal operation.  What does your hardware do for
this?

Bruce
Comment 5 Oliver B. Warzecha 2008-02-09 01:35:26 UTC
On Fri, Feb 08, 2008 at 11:30:12PM +1100, Bruce Evans wrote:
> On Wed, 6 Feb 2008, Oliver B. Warzecha wrote:
> 
> >Addon to my last mail, as I just discovered the i440BX-Specs, just
> >2 clicks away from one of the pages where I last searched for info.
> >They are downloadable from
> >http://www.intel.com/design/intarch/datashts/290562.htm
> 
> I found I even have the 1998 version of that locally.

Note that I have a 430HX chipset, the datasheet of the 82371SB
is some kind of vague concerning the RTC access, in fact only
the NMI functionality seems documented there.

I also checked the ICH (i815) specs, on page 234 of the PDF
(p. 8-44) it says:
"Software must preserve the value of bit 7 at I/O addresses 70h and 74h.
When writing to these addresses, software must first read the value, 
and then write the same value for bit 7 during the sequential address
write."

Given that in the 440BX documentation there is a written "Attribute:
write-only", which is admittedly contradicted in the next sentence,
which you quoted below, it may well be that the access specification
for this particular address has changed over time. 

> >On page 84, there is specified that the RTC index register
> >is write only (as I found out in practical testing :-). And it
> 
> I think it actually says that the register is more or less readable
> "Reads ... flow through to the ISA bus, but no RT... will be generated".
> It says that the register is traditionally write-only.  However, ISTR
> successfully reading this register from debuggers on 5-10 machines
> over the last 15-20 years.

Well... IIRC a read of the register always resulted in 0xA9 here,
no matter what was written before. But "more or less readable"
seems to describe the status quo quite well. ;-)

Do you remember if there was any machine with a HX chipset in your
list of machines. Perhaps this is a peculiarity of the 82437SB.
I see that this chip (also called PIIX3) was also used in the VX chipset.

> Van Gilluwe's book published in 1993 or 1994 says that the index

Oh :-) This was the book that I thought to be helpful if 
after some googling.

> register is write-only and complains that h/w designers keep making
> the mistake of write-only registers.  Van Gilluwe gives mainly access
> methods that take not just 2, but 3 ISA accesses to the RTC ports, and
> 2 I/O delays of 1-16 usec to ensure slowing things down further.  The
> extra RTC access is to turn the NMI disable bit in the index register
> back off after turning it on together with setting the index.  It
> doesn't bother to preserve either the old or the new index, and always
> leaves the index set at 0.  This NMI bit is more portable than I thought
> -- the Intel data sheet documents it.  This much care with NMIs may
> be required if NMIs actually happen.  FreeBSD is generally careless
> with NMIs, and doesn't touch the NMI bit in its RTC access functions
> except to blindly clear it.

Mmmh... NMIs seem to be used for indicating ECC errors in RAM. But
this is a different story...

> The wording is: "[Index register]: latched by the real time clock...";
> [Data register]: Data written to standard RAM bank address selected
> by RTC Index...".  These descriptions conflict a bit.  The first one

I think this may be well the major problem here, that the
descriptions are less than clear and the specifications have varied
over the years.

> doesn't quite say that the data value at the time of the write to the
> index register is latched to be read by any later read of the data
> register, and the second one doesn't quite say that the index register
> is just a select (latched at the time of read of the data register)
> for the data.  The first behaviour can be tested for (try to latch the
> current seconds value and read the data register several seconds later
> and see if you got the old value (*)), but we know that it doesn't work
> like that on more machines, else my change would break most machines
> (RTC interrupts would be broken if reading the data register didn't
> give current data).

What is the call profile? Does "read same register again" happen in
the normal use case? Or maybe there are intermittent accesses which
mask the problem. It might even be depending on a running ntpd
or timed, which is correcting the RTC...

Also, this machine here is relatively slow (200 Mhz K6), it can also
be that on a faster machine the access follows up fast enough so
that the circuits behind that gate keep state (see my comment on
capacitors in a past mail).

> I think you just have unusual hardware, else more machines would have
> broken.  However, I fear there is a problem somewhere, since RTC
> interrupts broke a couple of times last week on my main machine (with
> a VIA VT8237(??) bridge).  It's surprising how well FreeBSD works with
> the statistics clock stopped.  I haven't looked at your other hardware
> reference yet.

Given this other reference I think that the problem might only occur in
this particular chip set (As I mentioned, it's the reference for
a  "PC on a PCI card" system which uses the 430HX). I don't think,
a 430HX is that unusual, although it's rapidly reaching highschool age.
Given that the problem only gets noticed when the machine boots up
under surveillance (When it gets switched on it does come up after some
minutes... if unattended, you might not notice the delay)

I just found I have another HX board lying around here (a P55T2P4 -
no SCSI and only 4 mem slots), maybe I can slap something together, so
I can check it with this one, major problem being the AT power supply.

A pragmatic solution would be to implement both the "secure" and the
"fast" strategy and to select the correct one at boot time after 
checking for signs that the "fast" does not work, for example.
A config option might be overkill. ;)

> (*) A quick test using ddb on my hardware shows that reading the data
> register for the seconds register gives its current value, not the
> value at the time of the write of the seconds register index (0) to
> the index register.  Then subsequent reads of the data register
> with no intervening write to the index register keep returning the
> current seconds register.  I tested using ddb, and trust ddb not to
> access the RTC in normal operation.  What does your hardware do for
> this?

Having played around with ddb now, how do you do it? I don't see any
possibility to access I/O space besides writing some assembler code.
Coming from a happy 6502/68k background, where all I/O was
memory mapped, I am scratching my head here. That the man page
for ddb needs an urgent update does not help here, too. So maybe
I missed the command, there seem to be roughly 4 dozen undocumented
options for show only.

OBW
Comment 6 Bruce Evans freebsd_committer freebsd_triage 2008-02-09 06:13:45 UTC
On Sat, 9 Feb 2008, Oliver B. Warzecha wrote:

> On Fri, Feb 08, 2008 at 11:30:12PM +1100, Bruce Evans wrote:
>> On Wed, 6 Feb 2008, Oliver B. Warzecha wrote:
>>
>>> Addon to my last mail, as I just discovered the i440BX-Specs, just
>>> 2 clicks away from one of the pages where I last searched for info.
>>> They are downloadable from
>>> http://www.intel.com/design/intarch/datashts/290562.htm
>>
>> I found I even have the 1998 version of that locally.
>
> Note that I have a 430HX chipset, the datasheet of the 82371SB
> is some kind of vague concerning the RTC access, in fact only
> the NMI functionality seems documented there.

I happen to have an old BX system online.  It is my only system handy
that has an unreadable port 0x70:

%%%
Intel 82371AB/EB/MB PIIX4/4E/4M ISA Bridge on an Abit BP6
     port 0x70 is w/o (reads return 0xff)
     optimized RTC accesses work
NVIDIA nForce MCP2 ISA Bridge on an ASUS A7N8X-E
     port 0x70 is r/w
     optimized RTC accesses work
VIA VT8237(??) PCI to ISA Bridge on a Gigabyte K8VT800
     port 0x70 is r/w
     optimized RTC accesses work
ATI <card=0x30b0103c chip=0x43771002> PCI-ISA bridge on an HP nx6325
     port 0x70 is r/w
     optimized RTC accesses work
%%%

> I also checked the ICH (i815) specs, on page 234 of the PDF
> (p. 8-44) it says:
> "Software must preserve the value of bit 7 at I/O addresses 70h and 74h.
> When writing to these addresses, software must first read the value,
> and then write the same value for bit 7 during the sequential address
> write."

Maybe it is actually readable on the i815.

On my 82371, FreeBSD never sets the NMI bit in writes, so the read
return of 0xff indicates that even the NMI bit is w/o.

> Given that in the 440BX documentation there is a written "Attribute:
> write-only", which is admittedly contradicted in the next sentence,
> which you quoted below, it may well be that the access specification
> for this particular address has changed over time.

Or it may be w/o mainly on original ATs and Intel chipsets.

> Do you remember if there was any machine with a HX chipset in your
> list of machines. Perhaps this is a peculiarity of the 82437SB.
> I see that this chip (also called PIIX3) was also used in the VX chipset.

I think I had nothing between PIIX1 and PIIX4 except some other VIA
chipsets.  The system with the PIIX1 still works but is not worth
turning on even for testing :-).

>> doesn't quite say that the data value at the time of the write to the
>> index register is latched to be read by any later read of the data
>> register, and the second one doesn't quite say that the index register
>> is just a select (latched at the time of read of the data register)
>> for the data.  The first behaviour can be tested for (try to latch the
>> current seconds value and read the data register several seconds later
>> and see if you got the old value (*)), but we know that it doesn't work
>> like that on more machines, else my change would break most machines
>> (RTC interrupts would be broken if reading the data register didn't
>> give current data).
>
> What is the call profile? Does "read same register again" happen in
> the normal use case? Or maybe there are intermittent accesses which
> mask the problem. It might even be depending on a running ntpd
> or timed, which is correcting the RTC...

The RTC is almost never accessed accept by rtcintr(), and with LAPIC
timer interrupts rtcintr() is not used.  At least a few years ago, the
only other RTC accesses were for reading the time and initializing the
RTC and the fd driver on bootup, for setting the time later, and for
APM and maybe ACPI to reinitialize the RTC after un-suspend (the
un-suspend hook seems to be broken on amd64).  ntpd only sets the RTC
when it steps the clock; slews by ntpd and timed only do micro-adjustments
which don't affect the RTC.  Since the RTC is rarely accessed by
anything except rtcintr(), missing locking for the accesses rarely
mattered.  (The locking is mostly fixed now.)

> Also, this machine here is relatively slow (200 Mhz K6), it can also
> be that on a faster machine the access follows up fast enough so
> that the circuits behind that gate keep state (see my comment on
> capacitors in a past mail).

There would only be timing preoblems like that if the hardware is really
primitive or has weird latching semantics.  I see no problems with the
index and data register accesses separated by many seconds due to my
typing in the accesses in ddb.

> Given this other reference I think that the problem might only occur in
> this particular chip set (As I mentioned, it's the reference for
> a  "PC on a PCI card" system which uses the 430HX). I don't think,
> a 430HX is that unusual, although it's rapidly reaching highschool age.
> Given that the problem only gets noticed when the machine boots up
> under surveillance (When it gets switched on it does come up after some
> minutes... if unattended, you might not notice the delay)

I checked your other reference, where the need to rewrite the index
register but not much else is clearly stated.  Was that for the 430HX?

> I just found I have another HX board lying around here (a P55T2P4 -
> no SCSI and only 4 mem slots), maybe I can slap something together, so
> I can check it with this one, major problem being the AT power supply.

My PIIX1 is on the slghtly earlier and/or lower end P55TP4XE.

> A pragmatic solution would be to implement both the "secure" and the
> "fast" strategy and to select the correct one at boot time after
> checking for signs that the "fast" does not work, for example.
> A config option might be overkill. ;)

Any configuration might be overkill.

>> (*) A quick test using ddb on my hardware shows that reading the data
>> register for the seconds register gives its current value, not the
>> value at the time of the write of the seconds register index (0) to
>> the index register.  Then subsequent reads of the data register
>> with no intervening write to the index register keep returning the
>> current seconds register.  I tested using ddb, and trust ddb not to
>> access the RTC in normal operation.  What does your hardware do for
>> this?
>
> Having played around with ddb now, how do you do it? I don't see any
> possibility to access I/O space besides writing some assembler code.
> Coming from a happy 6502/68k background, where all I/O was
> memory mapped, I am scratching my head here. That the man page
> for ddb needs an urgent update does not help here, too. So maybe
> I missed the command, there seem to be roughly 4 dozen undocumented
> options for show only.

It's just "call inb(port) and call outb(port, data)", where inb() and
outb() are ordinary functions whose sole purpose is to let ddb call
them (the kernel uses inline or different versions of these in normal
operations).  ddb can call any function (but most not safely, and these
not safely unless the parameters are safe) and the man page is too small
to list them all.  I sometimes miss inw/outw/inl/outl but am too lazy
to add these to ddb.  My 1980's debugger has these.  Ports could also
be mapped to (virtual) memory so that you can examine and write to them
using memory access commands and not have to learn a different and less
convenient set of commands.  My 1980's debugger doesn't do this but copies
DOS DEBUG with minor improvements.

Bruce
Comment 7 Oliver B. Warzecha 2008-02-10 00:50:39 UTC
On Sat, Feb 09, 2008 at 05:13:45PM +1100, Bruce Evans wrote:
> I happen to have an old BX system online.  It is my only system handy
> that has an unreadable port 0x70:

So maybe someone had realised afterwards that it was a good idea[TM] to
make that port readable.

> There would only be timing preoblems like that if the hardware is really
> primitive or has weird latching semantics.  I see no problems with the
> index and data register accesses separated by many seconds due to my
> typing in the accesses in ddb.

So do I. (see below)

> I checked your other reference, where the need to rewrite the index
> register but not much else is clearly stated.  Was that for the 430HX?

It is clearly mentioned that this design is based on the 430HX, but
this is not detailed further. But it seems this is no longer a point
of concern...

> It's just "call inb(port) and call outb(port, data)", where inb() and
> outb() are ordinary functions whose sole purpose is to let ddb call
> them (the kernel uses inline or different versions of these in normal
> operations).  ddb can call any function (but most not safely, and these

I knew only the macro incarnations. No man page either, I was already
looking for such functions. :-/

Anyway, I checked, and inb(0x71) consistently returns the current second.
While I was at it I also tried 'call rtcin(0)' and it also returns
the correct result. So the routine works, taken for itself.
The question is, why doesn't it work in the loop?

I took some time and singlestepped calibrate_clocks(), needless to say,
it all works perfectly that way. As it has to be some kind of timing issue,
I went to some effort, maxed out the ISA I/O recovery cycles in the BIOS
settings and finally turned the CPU caches off. But although the
system was _definitely_ slower with each change, no result. Still
timeout. Any idea?

I guess I am back to inserting random inb(0x84) for now. Perhaps I
missed one combination the last time. :-P

OBW
Comment 8 Remko Lodder freebsd_committer freebsd_triage 2010-07-14 10:26:59 UTC
Responsible Changed
From-To: freebsd-i386->brde

Seems that Bruce has smart ideass about this, so make him responsible :-)
Comment 9 Remko Lodder freebsd_committer freebsd_triage 2010-07-14 11:08:31 UTC
Responsible Changed
From-To: brde->bde

Today we call Bruce bde instead of brde, 'whats in the name' :-)
Comment 10 Eitan Adler freebsd_committer freebsd_triage 2017-12-31 07:59:43 UTC
For bugs matching the following criteria:

Status: In Progress Changed: (is less than) 2014-06-01

Reset to default assignee and clear in-progress tags.

Mail being skipped
Comment 11 Warner Losh freebsd_committer freebsd_triage 2019-01-07 05:08:33 UTC
Collin changed the calibration code, so it's nothing like it was.
Closing as OBE.