testbios and the system timer
I've been pouring over various logs from testbios and what my M1 Vbios does in various conditions. Man what a bitch. One thing I've found testbios dosen't handle properly is the 8254 system 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. I'm guesing that what it uses for delays. Since I'm lucky enought to have the Vbios source I did some grep work and found out that indeed it uses timer 0 for delays. With preset delays ranging from 2uS all the way to 50mS and a generic delay that delays CX number of 1mS loops. The delay routine is written such that it polls for a rollover to mark the increment of 838.1 ns. For this to happen the latch values must be equal. In a system where the cpu instructions are running much faster than one timer clock cycle I guess would not be much of a problem. Of course the emulator totally munges this system since the elapsed timer ticks between timer reads for the emulator is way longer than one timer tick and its just blind chance when the timer delay routine reads the value it needs. What I don't understand though was how this ever was reliable. Don't ISA cycles take ~.6us to complete? So 1 out and 2 ins to the legach time thats 1.8us which should be 2 ticks so the routine should miss. I must not fully understand the delay routine. (Yes I have permission to post this snippit) Consider the following: DX = entry latch value AX = sucessive latch values BX = number of loops to do enter: read timer and store in DX loop: read the timer place result in AX sub AX,DX neg AX or AX,AX jnz check_loops and bl,not 1 dec bx dec bx check_loops: cmp ax,bx jb loop exit: Am I missing somthing? What i've noticed that the emulator causes the Vbios to get stuck in some delay loops. Eventually it probally would exit but its currently making my logs huge and causing the knashing of much teeth. So I'm thinking that the emulator needs to intercept reads and writes to the system timer and provide a fake timer that increments 1 tick per some x instructions emulated. And hopfully the chips and the bioses that need this won't mind that the actuall delay is longer than what was requested. Any comments before I hack this in? I'm off to bed. ___ Linuxbios mailing list [EMAIL PROTECTED] http://www.clustermatic.org/mailman/listinfo/linuxbios
Re: testbios and the system timer
On Thu, 2004-06-03 at 02:56, Richard Smith wrote: > > What i've noticed that the emulator causes the Vbios to get stuck in > some delay loops. Eventually it probally would exit but its currently > making my logs huge and causing the knashing of much teeth. > > So I'm thinking that the emulator needs to intercept reads and writes to > the system timer and provide a fake timer that increments 1 tick per > some x instructions emulated. And hopfully the chips and the bioses > that need this won't mind that the actuall delay is longer than what was > requested. > The original emulator in xfree86 use the system's gettimeofdate to emulate the timer. Since we are not going to have that function in linuxbios, I removed it. Probably we need an other way to emulate the timer. Ollie > Any comments before I hack this in? > > I'm off to bed. > > ___ Linuxbios mailing list [EMAIL PROTECTED] http://www.clustermatic.org/mailman/listinfo/linuxbios
Re: testbios and the system timer
On Thu, 3 Jun 2004, Li-Ta Lo wrote: > Probably we need an other way to emulate the timer. can we just read the timer? ron ___ Linuxbios mailing list [EMAIL PROTECTED] http://www.clustermatic.org/mailman/listinfo/linuxbios
Re: testbios and the system timer
On Thu, 2004-06-03 at 09:35, ron minnich wrote: > On Thu, 3 Jun 2004, Li-Ta Lo wrote: > > > Probably we need an other way to emulate the timer. > > can we just read the timer? > > ron > richard's point is that the emulator is much slower than the timer. The delay loop is facing overflow problem with the "emulated" io access to the "physical" counter. Ollie ___ Linuxbios mailing list [EMAIL PROTECTED] http://www.clustermatic.org/mailman/listinfo/linuxbios
Re: testbios and the system timer
On Thu, 3 Jun 2004, Li-Ta Lo wrote: > richard's point is that the emulator is much slower than the > timer. The delay loop is facing overflow problem with the > "emulated" io access to the "physical" counter. oops, sorry. Too much email this morning. I did not read his note carefully enough. Actually I'm surprised that the emulator is that much slower than an old 8086. OK, now what do we do ... Ah, we could use the TSC, right? ron ___ Linuxbios mailing list [EMAIL PROTECTED] http://www.clustermatic.org/mailman/listinfo/linuxbios
Re: testbios and the system timer
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? > I'm guesing that what it uses for delays. Indeed. It's the only way I know for measuring The delay routine is written such that it polls for a rollover to mark > the increment of 838.1 ns. For this to happen the latch values must be > equal. In a system where the cpu instructions are running much faster > than one timer clock cycle I guess would not be much of a problem. 838.1ns is one tick, not a complete 16-bit rollover, right? > What I don't understand though was how this ever was reliable. [..] > Consider the following: [..asm..] > Am I missing somthing? The resolution could be lowered.. Are there any writes to 0x40 setting a divisor? If not, then the snippet will simply not be reliable down to the exact iteration. Since the code uses jb to detect when to stop looping the count doesn't have to be an exact match. Even if an extra tick passes, the loop will still end. I don't think the timing is critical in any other way than that it should be as short as possible to keep the user happy, but with a minimum limit decided by hardware. //Peter ___ Linuxbios mailing list [EMAIL PROTECTED] http://www.clustermatic.org/mailman/listinfo/linuxbios
Re: testbios and the system timer
what about this. Build a composite timer with the top X bits coming from TSC, and the bottom Y bits coming from the time-of-day counter. Would that work? ron ___ Linuxbios mailing list [EMAIL PROTECTED] http://www.clustermatic.org/mailman/listinfo/linuxbios
Re: testbios and the system timer
OK, I finally read this in detail and I'm sorry for my noise on this subject. I think it would be useful to keep an 'emulated instruction count' in the emulator, and have a virtual timer that increments very X (pick a number) instructions. X can be constant across different architectures as we are somewhat divorced from time (it's an emulator). The emulated timer would increment every emulated instruction count ticks. Would this do it? ron ___ Linuxbios mailing list [EMAIL PROTECTED] http://www.clustermatic.org/mailman/listinfo/linuxbios
Re: testbios and the system timer
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? I don't thing so but that does explain why linux whines about "too many timer interrutps" occurring. The delay routine is written such that it polls for a rollover to mark the increment of 838.1 ns. For this to happen the latch values must be equal. In a system where the cpu instructions are running much faster than one timer clock cycle I guess would not be much of a problem. 838.1ns is one tick, not a complete 16-bit rollover, right? Yeah sorry. 838.1 ns is one tick. I said rollover which would be 50mS Re-looking at the delay routine I see I was mistaken as the delay routine counts ticks. Looking at the delay routine is just confusing. 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. 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. The resolution could be lowered.. Are there any writes to 0x40 setting a divisor? If not, then the snippet will simply not be reliable down to the exact iteration. Since the code uses jb to detect when to stop looping the count doesn't have to be an exact match. Even if an extra tick passes, the loop will still end. I don't understand. The part I'm refering to is the sub ax,dx neg ax or ax,ax jnz delay_a 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. Ate the timer reads really and ISA IO? 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. ___ Linuxbios mailing list [EMAIL PROTECTED] http://www.clustermatic.org/mailman/listinfo/linuxbios
Re: testbios and the system timer
ron minnich wrote: OK, I finally read this in detail and I'm sorry for my noise on this subject. I think it would be useful to keep an 'emulated instruction count' in the emulator, and have a virtual timer that increments very X (pick a number) instructions. X can be constant across different architectures as we are somewhat divorced from time (it's an emulator). The emulated timer would increment every emulated instruction count ticks. Would this do it? Yes. I think it would. Got any ideas on the implementation? I'm ready to try an implement this. ___ Linuxbios mailing list [EMAIL PROTECTED] http://www.clustermatic.org/mailman/listinfo/linuxbios
Re: testbios and the system timer
On Thu, 3 Jun 2004, Richard Smith wrote: > Yes. I think it would. Got any ideas on the implementation? I'm ready > to try an implement this. in the main loop for instruction decode there is a single instruction dispatch function. Create a global counter (emulate_counter?) and increment it once each time the dispatch function returns. You can in the emulator redirect I/O port access to a function. Write the code to handle read/write on those ports and use the emulate_counter to drive the clock value. ron ___ Linuxbios mailing list [EMAIL PROTECTED] http://www.clustermatic.org/mailman/listinfo/linuxbios
Re: testbios and the system timer
On Thu, 3 Jun 2004, Richard Smith wrote: > 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. All I know is BIOS code sucks and it looks like VGA BIOS code is worse than BIOS code. IT's amazing that any of it ever worked at all. ron ___ Linuxbios mailing list [EMAIL PROTECTED] http://www.clustermatic.org/mailman/listinfo/linuxbios
Re: testbios and the system timer
ron minnich wrote: On Thu, 3 Jun 2004, Richard Smith wrote: 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. Hold up. I'm baked. Gotta get more sleep. The above is obviously wrong. Its should be when they differ by 2. ___ Linuxbios mailing list [EMAIL PROTECTED] http://www.clustermatic.org/mailman/listinfo/linuxbios
Re: testbios and the system timer
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 :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. [..snip..] > 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) { bx=someunit dx=read_timer() do { ax=read_timer() ax=-(ax-dx) if(ax==0) bx=bx-(bx mod 2)-2 } while(ax 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. //Peter ___ Linuxbios mailing list [EMAIL PROTECTED] http://www.clustermatic.org/mailman/listinfo/linuxbios
Re: testbios and the system timer
ron minnich <[EMAIL PROTECTED]> writes: > You can in the emulator redirect I/O port access to a function. Write the > code to handle read/write on those ports and use the emulate_counter to > drive the clock value. Let me ask this quick question. Does the emulator restrict port I/O to just the resources on a particular VGA device? If not that is something we need to do to implement to ensure we flush these kinds of issues into the open and ensure the emulator is portable. Eric ___ Linuxbios mailing list [EMAIL PROTECTED] http://www.clustermatic.org/mailman/listinfo/linuxbios
Re: testbios and the system timer
Eric W. Biederman wrote: You can in the emulator redirect I/O port access to a function. Write the code to handle read/write on those ports and use the emulate_counter to drive the clock value. Let me ask this quick question. Does the emulator restrict port I/O to just the resources on a particular VGA device? If not that is something we need to do to implement to ensure we flush these kinds of issues into the open and ensure the emulator is portable. No. It allows full access to all IO ports. Otherwise it would have never been able to get to the system timer. So not only will it have to emulate x86 instructions it will have to emulate some of the generic x86 hardware setup. ___ Linuxbios mailing list [EMAIL PROTECTED] http://www.clustermatic.org/mailman/listinfo/linuxbios
Re: testbios and the system timer
Richard Smith <[EMAIL PROTECTED]> writes: > Eric W. Biederman wrote: > > >> You can in the emulator redirect I/O port access to a function. Write the > >> code to handle read/write on those ports and use the emulate_counter to drive > > >> the clock value. > > Let me ask this quick question. Does the emulator restrict port I/O to > > just the resources on a particular VGA device? If not that is something > > we need to do to implement to ensure we flush these kinds of issues > > into the open and ensure the emulator is portable. > > No. It allows full access to all IO ports. Otherwise it would have never been > able to get to the system timer. I was afraid of that. > So not only will it have to emulate x86 instructions it will have to emulate > some of the generic x86 hardware setup. Exactly. But in this case emulation is more predictable than making certain your hardware is setup in a legacy conforming mode. Eric ___ Linuxbios mailing list [EMAIL PROTECTED] http://www.clustermatic.org/mailman/listinfo/linuxbios
Re: testbios and the system timer
Eric W. Biederman wrote: No. It allows full access to all IO ports. Otherwise it would have never been able to get to the system timer. I was afraid of that. So not only will it have to emulate x86 instructions it will have to emulate some of the generic x86 hardware setup. Exactly. But in this case emulation is more predictable than making certain your hardware is setup in a legacy conforming mode. Hey, I'm totaly in agreement with you. No convincing necessary. *grin* It probally dosen't have to go all the way emulating a legacy PC enviroment but it looks like a few things will have to be dealt with. Restricting IO to legacy VGA registers and the allocated card IO locations is a good idea. That should flush out any other issues of this sort. There probally aren't that many though. In other news I recompiled my VBIOS with the delay routine just doing a 'ret' rathen then all that crazy timer stuff and testbios now completes on my target rather than going into the infinite loop it did before. Still don't get a signon message but it does do pretty much the same thing that ADLO+vbios does. H & V sync with the timeings correct for text mode but only a black screen. So thats some progress. Interesting to note that running the no-delay vbios on my desktop PCI works the same as with the delays. ___ Linuxbios mailing list [EMAIL PROTECTED] http://www.clustermatic.org/mailman/listinfo/linuxbios
Re: testbios and the system timer
On 8 Jun 2004, Eric W. Biederman wrote: > ron minnich <[EMAIL PROTECTED]> writes: > > You can in the emulator redirect I/O port access to a function. Write the > > code to handle read/write on those ports and use the emulate_counter to > > drive the clock value. > > Let me ask this quick question. Does the emulator restrict port I/O to > just the resources on a particular VGA device? If not that is something > we need to do to implement to ensure we flush these kinds of issues > into the open and ensure the emulator is portable. well, yes if you wish it to. That stuff is pretty configurable. Ollie is much more current than me on it -- he's hacking it. ron ___ Linuxbios mailing list [EMAIL PROTECTED] http://www.clustermatic.org/mailman/listinfo/linuxbios