testbios and the system timer

Peter Stuge stuge-linuxbios at cdy.org
Fri Jun 4 19:31:00 CEST 2004

On Thu, Jun 03, 2004 at 03:32:58PM -0500, Richard Smith wrote:
> Peter Stuge wrote:
> >On Thu, Jun 03, 2004 at 03:56:29AM -0500, Richard Smith wrote:
> >
> >>timer.  In numerious locations my Vbios is writing a 0x00 to IO 0x43 and 
> >>then does 2 reads from 0x40.  So its latching the value of counter 0 and 
> >>then reading it out.
> >
> >Right, it also sets counter mode 0, zero detection interrupt. Are
> >there any hints of the code actually using the interrupt anywhere?
> Um... I don't know.  What would I look for?

Someone writing a segment/offset pair to 0000:0020. (I.e. installing
an interrupt handler for IRQ0/INT8.)

> I don't thing so but that does explain why linux whines about "too
> many timer interrutps" occurring.

Yes, if the io accesses are let through the emulator to the real
hardware, that's certainly the reason.

You could probably test this, I did some quick testing and it looks
like Linux sets the timer divisor so that timer 0 runs at 1kHz.
Verify this (grep 0: /proc/interrupts && sleep && grep) followed by
a timed run of testbios. If there are extra interrupts on IRQ 0, the
real hardware was touched.

> Looking at the delay routine is just confusing.

I agree.

> There's a comment that says 4 bx counts equals .4290 * 4 or 2uS.
> So that tells me the VBios thinks the system timer must be running
> at 2.386 Mhz rather than the 1.19318 Mhz my PC hardware book claims.

1193180Hz doesn't change, that's the 4.77MHz clock divided by four,
your hardware book is correct. I used Ralf Brown's interrupt/port
list to refresh my own memory.

> All this tells me that I don't understand timer access in a modern 
> system.  The code as written just dosen't seem like it would work on a 
> 4.77 Mhz XT.

It may not neccessarily do so. The M1 is a PCI bus chip, right? I
can easily imagine that ATI didn't make the video BIOS XT compatible
for a graphics controller targeted at newer/mobile/embedded systems.


> This will only skip the jump (and do the BX decrement) if ax is
> zero. For ax to be zero the result of the 2's complement
> subtraction must be zero or the when the 2 reads are the same
> number.  But I just don't see how this would happen repeatably
> at .6us per ISA IO.

Hmm. Let's have another look at the code.

Ok. Pseudocode:

procedure delay(someunit) {
	do {
			bx=bx-(bx mod 2)-2
	} while(ax<bx)

It doesn't make a whole lot of sense, but eventually the loop will
end, since -(the_original_timer-current_timer) always gets compared
with the requested delay. If the (16bit) timer wraps, bx is
decreased but that's not really neccessary for the loop to ever end.

Conclusion; it not a very precise delay, it's just a suitably short
delay. :)

> Ate the timer reads really and ISA IO?

At least they used to be, port accesses on 486/Pentium took forever
and that's when I last did stuff like this and payed any attention
to how long it took. :)

> I guess if those reads are happening much faster then it would work.
> Where does the timer live now? int the northbridge perhpas?  Thats
> could be the issue.  If the northbridge  responded to the IO it
> would happen at cpu clock rates and all would be well.

Sure, it's part of the northbridge, but all sorts of buses are there,
I'd just put the timer where it has always been, on an ISA bus, to
minimize breakage. Although, lately I guess ISA isn't included in
chipsets, at least externally. LPC is handy for things like this and
of course runs a lot faster at 33MHz.


More information about the coreboot mailing list