[SeaBIOS] Re: [PATCH v2] timer: Handle decrements of PIT counter
On Fri, Jun 26, 2020 at 09:06:58PM +0300, Roman Bolshakov wrote: > There's a fallback to PIT if TSC is not present but it doesn't work > properly. It prevents boot from floppy on isapc and 486 cpu [1][2]. > > SeaBIOS configures PIT in Mode 2. PIT counter is decremented in the mode > but timer_adjust_bits() thinks that the counter overflows and increases > 32-bit tick counter on each detected "overflow". Invalid overflow > detection results in 55ms time advance (1 / 18.2Hz) on each read from > PIT counter. So all timers expire much faster and 5-second floppy > timeout expires in 83 real microseconds (or just a bit longer). > > It can be fixed by making the counter recieved from PIT an increasing > value so it can be passed to timer_adjust_bits(): > 0, 1, 2 and up to 65535 and then the counter is re-loaded with 0. > > 1. https://bugs.launchpad.net/seabios/+bug/1840719 > 2. https://lists.gnu.org/archive/html/qemu-devel/2019-08/msg03924.html Thanks. I committed this change. -Kevin ___ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-le...@seabios.org
[SeaBIOS] [PATCH v2] timer: Handle decrements of PIT counter
There's a fallback to PIT if TSC is not present but it doesn't work properly. It prevents boot from floppy on isapc and 486 cpu [1][2]. SeaBIOS configures PIT in Mode 2. PIT counter is decremented in the mode but timer_adjust_bits() thinks that the counter overflows and increases 32-bit tick counter on each detected "overflow". Invalid overflow detection results in 55ms time advance (1 / 18.2Hz) on each read from PIT counter. So all timers expire much faster and 5-second floppy timeout expires in 83 real microseconds (or just a bit longer). It can be fixed by making the counter recieved from PIT an increasing value so it can be passed to timer_adjust_bits(): 0, 1, 2 and up to 65535 and then the counter is re-loaded with 0. 1. https://bugs.launchpad.net/seabios/+bug/1840719 2. https://lists.gnu.org/archive/html/qemu-devel/2019-08/msg03924.html Fixes: eac11944019 ("Unify pmtimer_read() and pittimer_read() code.") Reported-by: Philippe Mathieu-Daudé Signed-off-by: Roman Bolshakov --- Changes since v1: - Simplified change of counter direction (Kevin) src/hw/timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hw/timer.c b/src/hw/timer.c index 56bb289..b6f102e 100644 --- a/src/hw/timer.c +++ b/src/hw/timer.c @@ -180,7 +180,7 @@ timer_read(void) // Read from PIT. outb(PM_SEL_READBACK | PM_READ_VALUE | PM_READ_COUNTER0, PORT_PIT_MODE); u16 v = inb(PORT_PIT_COUNTER0) | (inb(PORT_PIT_COUNTER0) << 8); -return timer_adjust_bits(v, 0x); +return timer_adjust_bits(-v, 0x); } // Return the TSC value that is 'msecs' time in the future. -- 2.26.1 ___ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-le...@seabios.org
[SeaBIOS] Re: [PATCH] timer: Handle decrements of PIT counter
On Fri, Jun 26, 2020 at 04:09:57PM +0300, Roman Bolshakov wrote: > On Tue, Jun 23, 2020 at 11:00:24PM -0400, Kevin O'Connor wrote: > > Good catch. Could we fix it using the patch below instead though? > > > > -Kevin > > > > > > --- a/src/hw/timer.c > > +++ b/src/hw/timer.c > > @@ -180,7 +180,7 @@ timer_read(void) > > // Read from PIT. > > outb(PM_SEL_READBACK | PM_READ_VALUE | PM_READ_COUNTER0, > > PORT_PIT_MODE); > > u16 v = inb(PORT_PIT_COUNTER0) | (inb(PORT_PIT_COUNTER0) << 8); > > -return timer_adjust_bits(v, 0x); > > +return timer_adjust_bits(-v, 0x); > > } > > > > // Return the TSC value that is 'msecs' time in the future. > > Hi Kevin, > > I like the approach much more. Initial count value is 0, PIT rearms the > timer when 1 is hit, unary negation on unsigned u16 fits perfectly, then > timer_adjust_bits recieves 0, 1, 2, ... and timer is rearmed at 0x. > > Do you want me to send v2 or you plan to apply the fix on your own? I'm fine with either. Thanks, -Kevin ___ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-le...@seabios.org
[SeaBIOS] Re: [PATCH] timer: Handle decrements of PIT counter
On Tue, Jun 23, 2020 at 11:00:24PM -0400, Kevin O'Connor wrote: > On Sat, Jun 13, 2020 at 02:19:12PM +0300, Roman Bolshakov wrote: > > There's a fallback to PIT if TSC is not present but it doesn't work > > properly. It prevents boot from floppy on isapc and 486 cpu [1][2]. > > > > SeaBIOS configures PIT in Mode 2. PIT counter is decremented in the mode > > but timer_adjust_bits() thinks that the counter overflows and increases > > 32-bit tick counter on each detected "overflow". Invalid overflow > > detection results in 55ms time advance (1 / 18.2Hz) on each read from > > PIT counter. So all timers expire much faster and 5-second floppy > > timeout expires in 83 real microseconds (or just a bit longer). > > > > Provide counter direction to timer_adjust_bits() and normalize the > > counter to advance ticks in monotonically increasing TimerLast. > > Good catch. Could we fix it using the patch below instead though? > > -Kevin > > > --- a/src/hw/timer.c > +++ b/src/hw/timer.c > @@ -180,7 +180,7 @@ timer_read(void) > // Read from PIT. > outb(PM_SEL_READBACK | PM_READ_VALUE | PM_READ_COUNTER0, PORT_PIT_MODE); > u16 v = inb(PORT_PIT_COUNTER0) | (inb(PORT_PIT_COUNTER0) << 8); > -return timer_adjust_bits(v, 0x); > +return timer_adjust_bits(-v, 0x); > } > > // Return the TSC value that is 'msecs' time in the future. Hi Kevin, I like the approach much more. Initial count value is 0, PIT rearms the timer when 1 is hit, unary negation on unsigned u16 fits perfectly, then timer_adjust_bits recieves 0, 1, 2, ... and timer is rearmed at 0x. Do you want me to send v2 or you plan to apply the fix on your own? If you plan to apply it on your own, here are the tags: Reviewed-by: Roman Bolshakov Tested-by: Roman Bolshakov Thanks, Roman ___ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-le...@seabios.org