VOGONS


First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

Anyone knows about boot problems with Windows 2000 on the i440fx chipset?

I keep getting a 7B inaccessable boot device BSOD during the first stage of setup(after loading all drivers from the CD-ROM).

This happens both with UniPCemu's PCI board and onboard i440fx for the hard/cd-rom drives.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 1 of 9, by bofh.fromhell

User metadata
Rank Oldbie
Rank
Oldbie

What motherboard are you trying to install on?
I have several different from Intel and ASUS and none of them has any problems installing W2K or XP.

I would first suspect memory tho.
Run memtest, and if that does not show errors try lowering the FSB.

Reply 2 of 9, by superfury

User metadata
Rank l33t++
Rank
l33t++
bofh.fromhell wrote on 2022-08-19, 04:18:
What motherboard are you trying to install on? I have several different from Intel and ASUS and none of them has any problems in […]
Show full quote

What motherboard are you trying to install on?
I have several different from Intel and ASUS and none of them has any problems installing W2K or XP.

I would first suspect memory tho.
Run memtest, and if that does not show errors try lowering the FSB.

It's a 82441fx/82442fx with 82371SB(PIIX3) that's emulated.
The BIOS ROM I'm using is the Asus C-P6ND dated 08/14/98 Award 4.51PG one from 86box.
Anything up to NT 4.0 workstation and 9x(95/98) boots properly.

I suspect some issues with the PCI ATA/ATAPI somehow, but most of the interface itself is undocumented(as in not specified at all in the PIIX3 documentation, as if non-existing, like BARs 0-3). All that's mentioned is the BAR4(for DMA).
The PCI IDE adapter can be either on an PC87415 cars or on the onboard i440fx one. Both crash in the same way (after "Starting Windows 2000..." is displayed).

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 3 of 9, by superfury

User metadata
Rank l33t++
Rank
l33t++

OK. Tried Windows 2000 setup on 440fx again on UniPCemu's latest version.

I saw just a little bit of ATA read/write activity (a few reads/writes to the ATA task file) after the Starting Windows 2000 now, although no commands were executed and it still throws a STOP 0x0000007b (0xFDC63848,0xC0000034,0x00000000,0x00000000)?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 4 of 9, by superfury

User metadata
Rank l33t++
Rank
l33t++

I did some more debugging of the "Starting Windows 2000..." and what it's doing.

I see it reading some sector, afterwards reading some registers (not logical?) and throwing the BSOD immediately after that?

The BIOS is somehow always corrupted somehow during boot for Windows 2000? The only fix atm seems to be replacing the ROM with a fresh unflashed copy (before the BIOS flashes anything new for it's parameter tables)?

Observerd crashes:
SCSI Port Driver crash @F000:F00A opcode FF /7=@1F00A=Corrupted BIOS!
Human Interface Parser crashes above as well? This is with the ROM BIOS?
So the BIOS gets corrupted at this point?

The final messages before the crash (Setup is loading files (insert below)...)):
Floppy Disk Driver
SCSI CD-ROM
SCSI Disk
SCSI Floppy Disk
FAT File System
Windows NT File System (NTFS)
CD-ROM File System

Then:
Starting Windows 2000...

(Paused at this point to activate the HDD debugging breakpoints, which is easy.)

*** new data ***

Write 08h to the channel 2 drive control register.
Write E0h to the channel 2 drive/head register.
Write 08h to the channel 2 drive control register.
Write E0h to the channel 2 drive/head register.
Write 08h to the channel 2 drive control register.
Write E0h to the channel 2 drive control register.
Read 50h from the channel 2 master status register.
Write E0 the the channel 2 drive/head register.
Read 50h from the channel 2 master status register.
"
Write 00h to the channel 2 features register.
Write 01h to the channel 2 sector count register.
Write 00h to the channel 2 sector number register.
Write 00h to the channel 2 cylinder low register.
Write 00h to the channel 2 cylinder high register.
Write E0h to the channel 2 drive/head register.
Read 50h from the channel 2 status register.
Write command C4 to the channel 2 master (executed).
Read 58h from the channel 2 status register.
"
Command finished properly.

Write 00h to channel 2 control register.
Write E0h to channel 2 drive/head register.
Write 08h to channel 2 control register.
Write E0h to channel 2 drive/head register.

CD-ROM action starts in "Windows 2000" boot:

Write A0h to channel 3 drive/head register.
Read 40h from channel 3 master status register.
Write A0h to channel 3 drive/head register.
Read 40h from channel 3 master status register.

Write 00h to channel 3 features register.
Write 00h to channel 3 cylinder low register.
Write 08h to channel 3 cylinder high register.
Write A0h to channel 3 drive/head register.
Read 40h from channel 3 master status register.
"
"
Write A0h to channel 3 command register (ATAPI PACKET command starting).
Read 80h from channel 3 master status register.
Read 48h from channel 3 master status register(ATAPI ready to receive packet).
"
UniPCemu Command parsing started after 6 words written: Read sector 10h from disc, length of 1 sector.
Read 80h from channel 3 master status register.
"
Read 48h from channel 3 master status register.
"
Read 02h from sector count register (ATAPI Interrupt Reason: Data In)
Read 48h from channel 3 master status register.
"
Entire sector is read from the buffer by the CPU.
Result phase IRQ reason is loaded and INTRQ is raised.
Read 40h from channel 3 master status register. INTRQ is lowered.
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
(Hmmm, were those supposed to be alternate status reads above?)
Read 40h from channel 3 status register.
"
"
"
"
"
"
Read 40h from channel 3 status register.
Read 40h from channel 3 status register.

(it looks like the BIOS code that's running at segment F000 is waiting for something on the status register to become busy???)

*** old data ***

Write channel 2 master: drive head=E0h
Write channel 2 control: 08h.
Write channel 2 master: drive head=E0h.
Write channel 3 master: drive head=A0h.
Write channel 3 master: drive head=A0h.
Read channel 3 master status: 40h.
Write channel 3 features: 00h.
Write channel 3 cylinder low: 00h.
Write channel 3 cylinder high: 80h.
Write channel 3 master: drive head=A0h.
Read channel 3 master status: 40h.
Read channel 3 master status: 40h.
"
Write channel 3 master command: A0h.
Read channel 3 status: 80h.
Read channel 3 status: 48h.
"
Read channel 3 status: 80h.
Command=28h.
Completes successfully?
Drive/head=A0h.
"
Features=00h.
Cylinder low=00h.
Cylinder high=80h.
Drivehead=A0h.
Command=A0h
Read sectors LBA=10h (1 sector).
Read sectorcount=02h.
Read sectors complete.

... long silence ...

Read cylinder high: 00h.
Read drive/head: A0h.

BSOD 7b (0xFDC63848,0xC0000034,0x00000000,0x00000000)
INACCESSIBLE_BOOT_DEVICE

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 5 of 9, by superfury

User metadata
Rank l33t++
Rank
l33t++

So, even though it's completed the read command, it keeps reading more and more data from the data port (the 440fx BIOS in this case)? Even though the interrupt it received was supposed to be a finishing interrupt (with interrupt reason 03h)?

Is the ATAPI device supposed to raise an IRQ when finishing a command (and the interrupt reason becomes 03h)?

Hmmm... For PIO ATAPI PACKET commands, is INTRQ supposed to be raised once the command completes?
The specs (sff8020i) seems to say that's the case, but in that case the BIOS misbehaves when reading CD-ROM sectors (since it starts reading junk out of the CD-ROM drive's data port)?
So perhaps it's just a little busy being raised instead of throwing an INTRQ when a command finishes?
Edit: Just changed the finishing of ATAPI SCSI commands to just become a little bit of busy timing and not raising an IRQ.
The Windows 2000 setup still seems to load from the CD-ROM? This might actually fix the BIOS issue that happens when starting the Windows 2000 setup?
Edit: Hmmm... For some reason the BIOS ROM at F000:xxxx keeps reading more data from the ATAPI data port when loading stuff from the CD-ROM, even though the status register already became 0x40 (because the block that's been requested has been fully read already)?
It thinks that the drive isn't busy and more data is ready to be read, even though it clearly isn't? The request for a sector(or multiple sectors for that matter) has already been completed, but the BIOS sees 0x40 in the status register and keeps reading it until it times out, after which it reads the data port of the ATAPI CD-ROM device to read zeroes because nothing is in the buffer?

Edit: Hmmm... Making the drive report busy while it's in the result busy phase (a small busy phase when entering the result phase) seems to cause the BIOS to stop reading those empty buffers of the ATAPI CD-ROM?
I've also increased the ATAPI result phase timeout from it's earlier 7us to 100us and made it report busy while the timeout is running (instead of being ready for the next command). That should make the BIOS at least properly detect the drive as being busy after a completed command (the 7us timeout was too small, the BIOS didn't even see it before it was already ready for a new command with the busy bit cleared).

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 6 of 9, by superfury

User metadata
Rank l33t++
Rank
l33t++

OK. Indeed, literally the first thing that happens when it says "Setup is starting Windows 2000" is resetting the hard drives with a SRST reset.

So that makes it easy to debug (as the remainder of the loading of files from the CD-ROM doesn't touch it) with a breakpoint.

New behaviour:
I did some more debugging of the "Starting Windows 2000..." and what it's doing.

I see it reading some sector, afterwards reading some registers (not logical?) and throwing the BSOD immediately after that?

The BIOS is somehow always corrupted somehow during boot for Windows 2000? The only fix atm seems to be replacing the ROM with a fresh unflashed copy (before the BIOS flashes anything new for it's parameter tables)?

Observerd crashes:
SCSI Port Driver crash @F000:F00A opcode FF /7=@1F00A=Corrupted BIOS!
Human Interface Parser crashes above as well? This is with the ROM BIOS?
So the BIOS gets corrupted at this point?

The final messages before the crash (Setup is loading files (insert below)...)):
Floppy Disk Driver
SCSI CD-ROM
SCSI Disk
SCSI Floppy Disk
FAT File System
Windows NT File System (NTFS)
CD-ROM File System

Then:
Starting Windows 2000...

(Paused at this point to activate the HDD debugging breakpoints, which is easy.)

*** new data ***

Write 08h to the channel 2 drive control register.
Write E0h to the channel 2 drive/head register.
Write 08h to the channel 2 drive control register.
Write E0h to the channel 2 drive/head register.
Write 08h to the channel 2 drive control register.
Write E0h to the channel 2 drive control register.
Read 50h from the channel 2 master status register.
Write E0 the the channel 2 drive/head register.
Read 50h from the channel 2 master status register.
"
Write 00h to the channel 2 features register.
Write 01h to the channel 2 sector count register.
Write 00h to the channel 2 sector number register.
Write 00h to the channel 2 cylinder low register.
Write 00h to the channel 2 cylinder high register.
Write E0h to the channel 2 drive/head register.
Read 50h from the channel 2 status register.
Write command C4 to the channel 2 master (executed).
Read 58h from the channel 2 status register.
"
Command finished properly.

Write 08h to channel 2 control register.
Write E0h to channel 2 drive/head register.
Write 08h to channel 2 control register.
Write E0h to channel 2 drive/head register.

CD-ROM action starts in "Windows 2000" boot:

Write A0h to channel 3 drive/head register.
Read 40h from channel 3 master status register.
Write A0h to channel 3 drive/head register.
Read 40h from channel 3 master status register.

Write 00h to channel 3 features register.
Write 00h to channel 3 cylinder low register.
Write 08h to channel 3 cylinder high register.
Write A0h to channel 3 drive/head register.
Read 40h from channel 3 master status register.
"
"
Write A0h to channel 3 command register (ATAPI PACKET command starting).
Read 80h from channel 3 master status register.
Read 48h from channel 3 master status register(ATAPI ready to receive packet).
"
UniPCemu Command parsing started after 6 words written: Read sector 10h from disc, length of 1 sector.
Read 80h from channel 3 master status register.
"
Read 48h from channel 3 master status register.
"
Read 02h from sector count register (ATAPI Interrupt Reason: Data In)
Read 48h from channel 3 master status register.
"
Entire sector is read from the buffer by the CPU.
Result phase IRQ reason is loaded and INTRQ is raised.
Read C0h from channel 3 master status register. INTRQ is lowered.
"
"
"
Result phase ends and reports.
Read 40h from channel 3 master status register.

(the earlier bug in the BIOS with the invalid reads of data is showing up at this point again)

After that whole mess with invalid multiple reads from port 170 (due to it performing them anyways even though the status register is 40h (although starting out as c0h due to the result phase timing that's done now)), it continues on.

Write A0h to the drive/head register.
Read 40h from the master status register.
Write A0h to the drive/head register.
Read 40h from the master status register.

Write 00h to the features register.
Write 00h to the cylinder low register.
Write 08h to the cylinder high register.
Write A0h to the drive/head register.
Read 40h from the master status register.
"
"

Write A0h to the command register.
Read 80h from the master status register.
Preparation completes and hardware becomes ready to receive the packet.
Read 48h from the master status register.
"
Another packet for reading sector 0x10 from the CD-ROM is written.
Read 80h from the master status register.
"
Execution completes and data becomes ready to read.
Read 48h from the master status register.
"
Read 02h from the sector count register(Interrupt reason: Data In)
Read 48h from the master status register.
"
Data transfer completes as all data is read
Read C0 from the master status register.
"
"
"
Result pending status completes. Result phase is entered and interrupt reason loaded. No interrupt is thrown.
Read 40h from the master status register.
"
"
"
"
etc.

BSOD 7b (0xFDC63848,0xC0000034,0x00000000,0x00000000)
INACCESSIBLE_BOOT_DEVICE

Edit: OK. So since that's working again now, I've restored the IRQ to trigger at the end of the timeout of the result phase.
The BIOS still does weird things with Windows 2000 though. It keeps reading data when it shouldn't, not looking at the right flags to determine if the transfer has ended. I never once see it properly handling the result phase when a transfer ends(sector counte register being 03h). And it only seems to check that if the DRQ bit is set, which by definition isn't the case for the result phase (as documented, DRQ=0 in that case).

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 7 of 9, by superfury

User metadata
Rank l33t++
Rank
l33t++

OK... IDA to the rescue!

Found out that it isn't waiting for it to be busy and/or DRQ after completing that data input loop from the device at all.
After fully disassembling the code (from F000:962A (which is a loop instruction for reading data from the ) onwards) that executes right after the input loop, I see it doing the exact opposite.

First it checks and waits for DRQ to clear, followed by BSY to clear. So far everything normal (theoretically).
Then it waits for BSY to set, which sets AH to 80h if it times out, 00h otherwise.

Looking at the code executing during the Boot from ATAPI CD-ROM phase (before the boot loader starts) it looks just fine?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 8 of 9, by superfury

User metadata
Rank l33t++
Rank
l33t++

OK. Ran MemTest86 (the https://www.memtest86.com/download.htm memtest free edition iso seems to crash for some weird reason, probably due to some weird CPU or software bug), which caused some memory location (9E0000+14h) to be cleared and immediately after that (writing 00100000 to 9E0000+04h and 0 to 9E0000+14) hanging on waiting for 9E000+14 to be non-zero, which will never happen).

MemTest86 seems to succeed however:

The attachment 1606-MemTest86 passes tests.png is no longer available

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 9 of 9, by superfury

User metadata
Rank l33t++
Rank
l33t++

OK. Looking at Windows 2000 setup starting it's Windows 2000 phase, I see something interesting:
F9000
F1000
F2000
F3000
F4000
F5000
F7000

All those have a TLB tag ending with 0xD, thus:
01101 in binary.
SDWU1 is are the bits stored.

S=Large
D=Dirty
W=Writable
U=User
That final 1 is a special bit, essentially a tag present bit.

So that means those pages are in the TLB cache as Writable.
But looking at the precalcs for the F0000-FFFFF area:
Reads:
1 for entries 0&1 and 8 and up. Others 0.
Writes:
All entries 0.

For those read and write entries, the final entry is for the 0x80000-0xA0000 memory area, the others are for 0xC0000-0x100000 memory area (basically the UMA in MS-DOS), in 4000h chunks (16KB chunks). Those are the precalculated memory mappings for the i430fx/i440fx RAM/ROM read/write mapping (as configured in the chipset PCI space).

For those entries, 0 means map to ROM(not RAM), 1 means map to DRAM and 2 means unmapped completely.

So for the C0000-C8000 it's read from RAM, write to ROM.
Then for entries 2-7(which is C8000-E0000) it's read from ROM, write to ROM.
Entries 8 through F (E0000-100000) it's read from RAM, write to ROM.
And entry 10h (the 512K-640K memory block) it's read from RAM, write to ROM.

Now, look at where the pages in the TLB are pointing:
F1000-F5FFF,F7000-F7FFF and F9000-F9FFF, all read/write.
That it's mapped read from RAM is fine. That means that the RAM reads are succeeding there.
But it's all mapped to write to ROM instead of actual RAM! So if Windows 2000 writes anything there, it gets into a black hole of sorts, since there's no RAM there (or writing to the BIOS flash ROM if writes to it are allowed by the BIOS)!

Now, looking at the PAM registers, I see:
59h=10h
5Ah=11h
5Bh-5Dh=00h
5E-5Fh=11h

So that means:
For 59h: F0000-FFFFF: RE without WE.
For 5Ah: C0000-C7FFF: RE without WE.
For 5B-5Dh: C8000-DFFFF: Neither RE nor WE.
For 5E-5Fh: E0000-EFFFF: RE without WE.

So for RE only being set without WE, it means read from DRAM and writes to PCI.
For neither being set, it means reads and writes from PCI.

So basically it's readable RAM(normal as you would expect) but writes are redirected to PCI!
So basically it's RAM mapped as ROM right there! If Windows 2000 writes anything to it though, it will always redirect to PCI (ROM)!

I don't think that WIndows 2000 would like for it to be writing any memory data to a ROM (it's clearly mapped it as read/write in the TLB)?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io