ASPI2DOS.SYS and KEYB.COM from Win 98 SE installation CD (and most likely other DOS versions too) depend on I/O port 0x61 bit 4 to be toggled. This requires timer 1 (I/O 0x41, legacy DRAM refresh) to be correctly set. Also Intel ICH7 Family Datasheet, chapter 5.8 states:
Programming the counter to anything other than Mode 2 will result in undefined behavior for the REF_TOGGLE bit.
Failing to have the timer 1 configured indeed causes affected OSes to freeze during the boot.
Signed-off-by: Petr Cvek petrcvekcz@gmail.com --- src/hw/timer.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/src/hw/timer.c b/src/hw/timer.c index b6f102e..b272f44 100644 --- a/src/hw/timer.c +++ b/src/hw/timer.c @@ -280,4 +280,10 @@ pit_setup(void) // maximum count of 0000H = 18.2Hz outb(0x0, PORT_PIT_COUNTER0); outb(0x0, PORT_PIT_COUNTER0); + + // timer1: binary count, 16bit count, mode 2 + outb(PM_SEL_TIMER1|PM_ACCESS_WORD|PM_MODE2|PM_CNT_BINARY, PORT_PIT_MODE); + // maximum count of 0012H = 66.3kHz + outb(0x12, PORT_PIT_COUNTER1); + outb(0x0, PORT_PIT_COUNTER1); }
On Wed, Jul 13, 2022 at 03:25:17AM +0200, Petr Cvek wrote:
ASPI2DOS.SYS and KEYB.COM from Win 98 SE installation CD (and most likely other DOS versions too) depend on I/O port 0x61 bit 4 to be toggled. This requires timer 1 (I/O 0x41, legacy DRAM refresh) to be correctly set. Also Intel ICH7 Family Datasheet, chapter 5.8 states:
Programming the counter to anything other than Mode 2 will result in undefined behavior for the REF_TOGGLE bit.
Failing to have the timer 1 configured indeed causes affected OSes to freeze during the boot.
Thanks. In general, I don't see an issue with initializing standard hardware. However, a change like this could have a subtle impact on existing installations. So, I'd like to have a better understanding of this change.
Did the above compatibility issue occur on coreboot or on QEMU? If on coreboot, can you check if the problem exists on QEMU? If it isn't an issue on QEMU, do you know why? Finally, have you found any documents that describe how timer1 is intended to be configured on legacy systems?
Thanks again, -Kevin
Signed-off-by: Petr Cvek petrcvekcz@gmail.com
src/hw/timer.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/src/hw/timer.c b/src/hw/timer.c index b6f102e..b272f44 100644 --- a/src/hw/timer.c +++ b/src/hw/timer.c @@ -280,4 +280,10 @@ pit_setup(void) // maximum count of 0000H = 18.2Hz outb(0x0, PORT_PIT_COUNTER0); outb(0x0, PORT_PIT_COUNTER0);
- // timer1: binary count, 16bit count, mode 2
- outb(PM_SEL_TIMER1|PM_ACCESS_WORD|PM_MODE2|PM_CNT_BINARY, PORT_PIT_MODE);
- // maximum count of 0012H = 66.3kHz
- outb(0x12, PORT_PIT_COUNTER1);
- outb(0x0, PORT_PIT_COUNTER1);
}
2.37.0
SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org
Kevin O'Connor wrote:
Also Intel ICH7 Family Datasheet, chapter 5.8 states:
Programming the counter to anything other than Mode 2 will result in undefined behavior for the REF_TOGGLE bit.
Failing to have the timer 1 configured indeed causes affected OSes to freeze during the boot.
Thanks. In general, I don't see an issue with initializing standard hardware.
While I agree that this change is needed somewhere, doesn't PIT initialization actually belong in coreboot?
However, a change like this could have a subtle impact on existing installations.
I don't think it will. Counter 1 should be running but is not.
Programs that expect it to be running currently hang.
Per the ICH6 datasheet, counter 1 output is not connected to any interrupt controller input, although I do vaguely remember using IRQ 1 interrupts which occured at a higher rate than IRQ 0 on AT hardware.
ICH6 datasheet also says "A new initial count may be written to a counter at any time without affecting the counter's programmed mode. Counting is affected as described in the mode definitions."
So any programs that would reconfigure the RAM refresh request signal counter (I think highly unlikely) don't care if it's already running.
Finally, have you found any documents that describe how timer1 is intended to be configured on legacy systems?
Hm, what qualifies as legacy systems? The ICH7 datasheet was quoted, ICH6 datasheet concurs. Yet another reference is Ralf Brown's interrupt list, mentioning XT and AT:
--8<-- PORTS.LST ----------P0040005F-------------------------- PORT 0040-005F - PIT - PROGRAMMABLE INTERVAL TIMER (8253, 8254) Notes: XT & AT use ports 40h-43h; PS/2 uses ports 40h, 42h-44h, and 47h the counter chip is driven with a 1.193 MHz clock (1/4 of the original PC's 4.77 MHz CPU clock) SeeAlso: PORT 0044h,PORT 0048h
0040 RW PIT counter 0, counter divisor (XT, AT, PS/2) Used to keep the system time; the default divisor of (1)0000h produces the 18.2Hz clock tick. 0041 RW PIT counter 1, RAM refresh counter (XT, AT) don't set below 3 on PCs (default 12h), and don't mess with this counter at all unless you really know what you're doing.... -->8--
Kind regards
//Peter
Dne 05. 08. 22 v 20:18 Kevin O'Connor napsal(a):
On Wed, Jul 13, 2022 at 03:25:17AM +0200, Petr Cvek wrote:
ASPI2DOS.SYS and KEYB.COM from Win 98 SE installation CD (and most likely other DOS versions too) depend on I/O port 0x61 bit 4 to be toggled. This requires timer 1 (I/O 0x41, legacy DRAM refresh) to be correctly set. Also Intel ICH7 Family Datasheet, chapter 5.8 states:
Programming the counter to anything other than Mode 2 will result in undefined behavior for the REF_TOGGLE bit.
Failing to have the timer 1 configured indeed causes affected OSes to freeze during the boot.
Thanks. In general, I don't see an issue with initializing standard hardware. However, a change like this could have a subtle impact on existing installations. So, I'd like to have a better understanding of this change.
Did the above compatibility issue occur on coreboot or on QEMU? If on coreboot, can you check if the problem exists on QEMU? If it isn't an issue on QEMU, do you know why? Finally, have you found any documents that describe how timer1 is intended to be configured on legacy systems?
I've found it when trying to boot windows 98 SE installation under coreboot. Inside QEMU the test for I/O port 0x61 bit 4 succeeds (no hang up). It seems the QEMU has the timer 1 already enabled.
One of the multiple checks in KEYB.COM
00000F44 E461 in al,0x61 00000F46 2410 and al,0x10 00000F48 3AC4 cmp al,ah 00000F4A 74F8 jz 0xf44
If the timer is disabled (and other bit state is required by cmp) the test will spin forever.
I've tried to check on a real hardware if the timer is stopped and indeed it was. After a manual configuration in a debugger the KEYB.COM succeeded to run.
So far I've found the timer 1 description in the ICH7 datasheet:
IntelĀ® I/O Controller Hub 7 (ICH7) Family
Section 5.8 8254 Timers (D31:F0)
The REF_TOGGLE bit will have a square wave behavior (alternate between 0 and 1) and will toggle at a rate based on the value in the counter. Programming the counter to anything other than Mode 2 will result in undefined behavior for the REF_TOGGLE bit.
(the alternation between 0 and 1 is used by those DOS programs)
There is actually a setup function in coreboot, but it is called in a specific case, when video bios is executed in a realmode environment.
The divider value is taken from there (also I've seen the same value in MSDOS age documentation).
https://elixir.bootlin.com/coreboot/4.17/source/src/drivers/pc80/pc/i8254.c#...
(I'm not sure the values there are correct too, ICH7 datasheet says MODE2 and maybe MSB should be erased also, I've set WIP patch at
https://review.coreboot.org/c/coreboot/+/65809
but that's slightly OT)
Petr
Thanks again, -Kevin
Signed-off-by: Petr Cvek petrcvekcz@gmail.com
src/hw/timer.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/src/hw/timer.c b/src/hw/timer.c index b6f102e..b272f44 100644 --- a/src/hw/timer.c +++ b/src/hw/timer.c @@ -280,4 +280,10 @@ pit_setup(void) // maximum count of 0000H = 18.2Hz outb(0x0, PORT_PIT_COUNTER0); outb(0x0, PORT_PIT_COUNTER0);
- // timer1: binary count, 16bit count, mode 2
- outb(PM_SEL_TIMER1|PM_ACCESS_WORD|PM_MODE2|PM_CNT_BINARY, PORT_PIT_MODE);
- // maximum count of 0012H = 66.3kHz
- outb(0x12, PORT_PIT_COUNTER1);
- outb(0x0, PORT_PIT_COUNTER1);
}
2.37.0
SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org