csmwrap icon indicating copy to clipboard operation
csmwrap copied to clipboard

VGA BIOS Option ROM

Open mintsuki opened this issue 7 months ago • 58 comments

Forgive the perhaps silly question, but does this execute a VGA card's video BIOS option ROM, if present?

That is the best way (and only real way as far as I know) to obtain legacy-compatible video modes on a UEFI system (and yes, it will need a PCI video card shipping a legacy compatible video BIOS, but that's been the case for several generations of Intel/AMD systems now, even those supporting CSM natively).

Without this, the emulation of legacy video modes will never be capable enough to properly run a vast majority of legacy OSes and applications expecting proper legacy video modes/VGA stuff to work...

Thanks in advance for any kind reply.

mintsuki avatar May 17 '25 07:05 mintsuki

No at the moment, but I'm trying to implement this functionality.

For now it uses VBIOS implemented by SeaBIOS unconditionally, which will draw onto framebuffer setup by UEFI GOP. This is pretty capable and VBE 3.0 compliment.

For native VBIOS, I met some issues on my first attempt, will try to work out a solution.

FlyGoat avatar May 17 '25 09:05 FlyGoat

Some progress on this topic, I managed to get native VBIOS working with R5 230 (which only provides a legacy OpROM).

However, on RX550 it seems like PciIo->RomImage only contains EFI GOP OpROM. I'm sure the card provide a legacy OpROM as well because I can dump it in Linux driver. I think it's a policy of UEFI PCIBus driver's OpROM copy mechanism.

Reading the on card ROM is not a trivial task, as ROM BAR of the card was left disabled by the firmware, we need to allocate a range for it, which seems out of scope of EFI BootService. We may need to write a resource allocator on our own. In worst case, we may need to enlarge the low 4G PCI Hole to accommodate it.

Anyway, I'll try to make some progress.

FlyGoat avatar May 18 '25 15:05 FlyGoat

Very happy to hear that progress is being made! I tried to look into it myself as well yesterday, but made little progress.

Even if in the end this only works for older cards, it's still better than nothing. This issue is really fundamental as far as this project goes since it's the n.1 issue that sits between a good CSM-on-EFI and an unacceptably limited one.

As I mentioned yesterday, I am more than happy to run tests for you if you want me to!

mintsuki avatar May 18 '25 18:05 mintsuki

I have an idea - how about instead of SeaVGABIOS or graphics card VBIOS use fake int10 like OVMF or UefiSeven does - inserts fake int10 into memory at address C0000 - with this WinXP work OK on pure UEFI. UEFI use GOP for boot PC but WinXP use fake int10 from C0000 memory and works on standard vga.sys driver:

QEMU:

000C0000   56 45 53 41 00 03 22 00 00 C0 01 00 00 00 27 00   VESA..".......'.
000C0010   00 C0 30 00 00 00 2B 00 00 C0 30 00 00 C0 3D 00   ..0...+...0...=.
000C0020   00 C0 51 45 4D 55 00 F1 00 FF FF 4F 56 4D 46 00   ..QEMU.....OVMF.
000C0030   51 45 4D 55 20 51 58 4C 20 56 47 41 00 4F 56 4D   QEMU QXL VGA.OVM
000C0040   46 20 49 6E 74 31 30 68 20 28 66 61 6B 65 29 00   F Int10h (fake).
000C0050   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
000C0060   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................

UefiSeven:

000C0000   56 45 53 41 00 03 22 00 00 C0 01 00 00 00 2C 00   VESA..".......,.
000C0010   00 C0 30 00 00 00 30 00 00 C0 3A 00 00 C0 47 00   ..0...0...:...G.
000C0020   00 C0 55 65 66 69 53 65 76 65 6E 00 F1 00 FF FF   ..UefiSeven.....
000C0030   55 65 66 69 53 65 76 65 6E 00 45 6D 75 6C 61 74   UefiSeven.Emulat
000C0040   65 64 20 56 47 41 00 4F 56 4D 46 20 49 6E 74 31   ed VGA.OVMF Int1
000C0050   30 68 20 28 66 61 6B 65 29 00 90 90 90 90 90 90   0h (fake).......
000C0060   90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90   ................

A long time ago I was doing tests with WinXP and inserted OptionROM VBIOS IBM-VGA.ROM, IBM-EGA.ROM into the bios and XP works without graphics card: https://www.elektroda.pl/rtvforum/viewtopic.php?p=11836500#11836500 The screenshot was taken over the network using a connection to the Remote Administrator server installed on this WinXP: Image

Gelip avatar May 18 '25 20:05 Gelip

Because IMO that isn't a real solution. Unless CSMWrap is meant solely to boot Windows NT, and it isn't, this is just a workaround and won't work with any real MS-DOS/9x/other stuff, as those all expect proper legacy video modes like especially text mode and friends, which are not emulatable the same way one can with linear framebuffers.

mintsuki avatar May 18 '25 20:05 mintsuki

I have an idea - how about instead of SeaVGABIOS or graphics card VBIOS use fake int10 like OVMF or UefiSeven does - inserts fake int10 into memory at address C0000 - with this WinXP work OK on pure UEFI with GOP on vga.sys driver:

I think SeaVGABIOS is much more capable then UefiSeven's fake int10h solution as it do have proper text mode implementation and so on. The only thing missing is real modesetting, which is only possible with hardware specific drivers like real Op ROM or GOP.

QEMU:

000C0000   56 45 53 41 00 03 22 00 00 C0 01 00 00 00 27 00   VESA..".......'.
000C0010   00 C0 30 00 00 00 2B 00 00 C0 30 00 00 C0 3D 00   ..0...+...0...=.
000C0020   00 C0 51 45 4D 55 00 F1 00 FF FF 4F 56 4D 46 00   ..QEMU.....OVMF.
000C0030   51 45 4D 55 20 51 58 4C 20 56 47 41 00 4F 56 4D   QEMU QXL VGA.OVM
000C0040   46 20 49 6E 74 31 30 68 20 28 66 61 6B 65 29 00   F Int10h (fake).
000C0050   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
000C0060   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................

UefiSeven:

000C0000   56 45 53 41 00 03 22 00 00 C0 01 00 00 00 2C 00   VESA..".......,.
000C0010   00 C0 30 00 00 00 30 00 00 C0 3A 00 00 C0 47 00   ..0...0...:...G.
000C0020   00 C0 55 65 66 69 53 65 76 65 6E 00 F1 00 FF FF   ..UefiSeven.....
000C0030   55 65 66 69 53 65 76 65 6E 00 45 6D 75 6C 61 74   UefiSeven.Emulat
000C0040   65 64 20 56 47 41 00 4F 56 4D 46 20 49 6E 74 31   ed VGA.OVMF Int1
000C0050   30 68 20 28 66 61 6B 65 29 00 90 90 90 90 90 90   0h (fake).......
000C0060   90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90   ................

FlyGoat avatar May 18 '25 20:05 FlyGoat

It has "text mode", but I wouldn't call it proper.

Most stuff that requires a proper text mode doesn't work with it - only very simple stuff like the COMMAND.COM prompt and very simple text programs work with it, but anything more complex that requires proper text mode will not work - from EDIT, to SCANDISK and so on and so forth.

The only real way to do proper text mode is to use a compatible GPU and the GPU's VBIOS as per title of this issue.

That isn't to say that a fallback is bad to have, but the fallback of SeaVGABIOS as it stands right now is pretty much the best you're gonna get.

mintsuki avatar May 18 '25 20:05 mintsuki

@FlyGoat Have you seen OpenCore's CSM implementation ? https://github.com/acidanthera/OpenCorePkg/pull/482

Instead of just using EFI_LEGACY_BIOS_PROTOCOL (which requires CSM support) like rEFInd they implemented all those calls themselves, probably because some Apple devices don't have it and they re-used that code for PC.

It only uses EFI_LEGACY_8259_PROTOCOL, though recent TianoCore verions (and I assume Arrow Lake) are missing that protocol and will need it implemented.

There's also a minimal VGA BIOS implementation (BiosVideo.c) which might be interesting.

https://www.intel.com/content/dam/www/public/us/en/documents/reference-guides/efi-compatibility-support-module-specification-v098.pdf might be of use too.

EDIT:

Weirdly I cannot find a single reference to ExitBootServices within it though, seems like they do that stuff manually instead for some reason. https://github.com/acidanthera/OpenCorePkg/blob/master/Platform/OpenLegacyBoot/LegacyBootSupport.c#L367

xCuri0 avatar May 19 '25 01:05 xCuri0

@FlyGoat Have you seen OpenCore's CSM implementation ? acidanthera/OpenCorePkg#482

Thanks for the pointer! I actually checked that a couple of days ago.

Instead of just using EFI_LEGACY_BIOS_PROTOCOL (which requires CSM support) like rEFInd they implemented all those calls themselves, probably because some Apple devices don't have it and they re-used that code for PC.

It's mostly the same as "Skylake+ PAM" fallback unlocking method implemented by CSMWrap.

It only uses EFI_LEGACY_8259_PROTOCOL, though recent TianoCore verions (and I assume Arrow Lake) are missing that protocol and will need it implemented.

There's also a minimal VGA BIOS implementation (BiosVideo.c) which might be interesting.

It also comes from EDK2, but I think this is not a VGA BIOS implementation? It somewhat tried to provide as GOP driver based on VESA VBIOS.

https://www.intel.com/content/dam/www/public/us/en/documents/reference-guides/efi-compatibility-support-module-specification-v098.pdf might be of use too.

EDIT:

Weirdly I cannot find a single reference to ExitBootServices within it though, seems like they do that stuff manually instead for some reason. https://github.com/acidanthera/OpenCorePkg/blob/master/Platform/OpenLegacyBoot/LegacyBootSupport.c#L367

FlyGoat avatar May 19 '25 07:05 FlyGoat

Just for recording, this is actual EDK2's legacy VBIOS handling code:

https://github.com/tianocore/edk2/blob/stable/202011/OvmfPkg/Csm/LegacyBiosDxe/LegacyPci.c

FlyGoat avatar May 19 '25 09:05 FlyGoat

I just implemented native VGA OpROM support, seems working on RX550, please check current main branch.

Thanks

FlyGoat avatar May 19 '25 17:05 FlyGoat

That's amazing, thank you so much! I'll definitely run some tests now and let you know.

mintsuki avatar May 19 '25 18:05 mintsuki

I just implemented native VGA OpROM support, seems working on RX550, please check current main branch.

Thanks

Is this solve VGA problem on GPUs which does not support Legacy OPROM?

ages2001 avatar May 19 '25 18:05 ages2001

I just implemented native VGA OpROM support, seems working on RX550, please check current main branch. Thanks

Is this solve VGA problem on GPUs which does not support Legacy OPROM?

Nah, for such GPU it should be handled by SeaVGABIOS.

FlyGoat avatar May 19 '25 18:05 FlyGoat

I tested on my ARL system with a GPU with a proper OpROM. CSMWrap seemed to say all was good with regards to that, until it got stuck at CALL16 f000:cda5 as mentioned in issue #16.

mintsuki avatar May 19 '25 19:05 mintsuki

I tested on my ARL system with a GPU with a proper OpROM. CSMWrap seemed to say all was good with regards to that, until it got stuck at CALL16 f000:cda5 as mentioned in issue #16.

My ARL system (Z890,H810 ) can not disable the above 4G MMIO function. Especially use AMD graphics cards 400s above.

Canonkong avatar May 19 '25 20:05 Canonkong

Neither can mine, as long as I have been able to find...

But is that an issue when using an older dedicated graphics card? Or is one forced to use an even older graphics card? Because I haven't tried with the oldest PCIe GPU I have yet...

mintsuki avatar May 19 '25 20:05 mintsuki

Neither can mine, as long as I have been able to find...

But is that an issue when using an older dedicated graphics card? Or is one forced to use an even older graphics card? Because I haven't tried with the oldest PCIe GPU I have yet...

I tested the Lenovo machines Q670 with 12-14th cpus, after disable above 4G Decoding and MMIO, they can work perfectly use csmwrap ver 1.1.0, but Z890/H810 can not. I tried to disable it use amisce and ru.efi,even use mod bios, but failed.

Canonkong avatar May 19 '25 20:05 Canonkong

I just refreshed seabios build to disable debug prints over serial, which seems causing problems.

If it's still not working, I'll look into getting debug prints via XHCI DbC.

FlyGoat avatar May 19 '25 20:05 FlyGoat

Tested again... No luck.

I even tried the aforementioned oldest PCIe graphics card I have, but that one didn't even get past POST (I assume because it needs a CSM-supporting firmware in order for modeset to be done).

I tried 2 different AMD GPUs on top of that, of different generations; one being an RX 550, and the other a HD6450 - no luck with either of them, it still gets stuck at the CALL16, albeit with a different offset now, but I assume that's due to the different SeaBIOS and matters little.

mintsuki avatar May 19 '25 21:05 mintsuki

Oh yeah, I forgot to mention that this machine has a COM port and I am willing and able to test using COM output, instead of going the XHCI route, if need be.

mintsuki avatar May 19 '25 21:05 mintsuki

Oh yeah, I forgot to mention that this machine has a COM port and I am willing and able to test using COM output, instead of going the XHCI route, if need be.

It would be nice if you can get logs from serial port :-) Any build prior to 27efbe7b6955a6a47d46579bdbb94f270b6355e1 will print logs on COM1.

Hopefully it's just some SeaBIOS glitch, debugging OpROM is really hard without proper tooling. Maybe it's possible to do it with VFIO.

FlyGoat avatar May 19 '25 22:05 FlyGoat

I can't seem to get any serial output out of this machine, sadly...

mintsuki avatar May 19 '25 23:05 mintsuki

At least that is without changing CSMWrap's code to address the COM port directly, which I'll likely attempt now.

mintsuki avatar May 19 '25 23:05 mintsuki

@Canonkong Legacy VBIOS should still work with 4G Decoding on, but at 640x480 and low bit depth because SVGA modes using VESA require a 32-bit framebuffer address retrieved through INT10H VESA calls, which cannot be passed because it's at a 64-bit address.

The legacy VGA modes with limited resolution/depth are at 0xA0000 which should work as long a legacy VGA decoding is enabled which to my knowledge csmwrap does try to. The chipset might play a role in this though even if the GPU supports it, which could be why it doesn't work on Arrow Lake.

I tested this myself with non-GOP VBIOS on RX 580 but it was on a platform where the chipset supports CSM.

Also FYI any 32-bit OS without PAE that tries to use PCIe devices will have issues with 4G decoding on. It is possible to re allocate and downsize BARs after boot though so it can be worked around on boards where 4G decoding is forced on.

xCuri0 avatar May 20 '25 00:05 xCuri0

I think we are not far from success. Testing on Q670 with intel 13th, above 4G MMIO disable, need to wait 1-2minutes,than it can work. Image

Canonkong avatar May 20 '25 01:05 Canonkong

I could not seem to get any output out of the ARL board's COM port... I am so disappointed with this platform, it's just so badly put together, insane Intel released this.

I'll try updating the BIOS to see if that makes any difference, but I'm doubtful it's gonna do anything.

mintsuki avatar May 20 '25 01:05 mintsuki

I could not seem to get any output out of the ARL board's COM port... I am so disappointed with this platform, it's just so badly put together, insane Intel released this.

I'll try updating the BIOS to see if that makes any difference, but I'm doubtful it's gonna do anything.

Can we use 1394 cards to debug it?I often use 1394 to make acpi.sys debug.

Canonkong avatar May 20 '25 01:05 Canonkong

Testing on Q670 with intel 13th and Nvidia GT730, above 4G MMIO Enable, need to wait 1-2minutes, it also can work. But can’t set the screen resolution, after install Nvidia graphics cards driver, all can work fine. Image

Canonkong avatar May 20 '25 02:05 Canonkong

I just implemented native VGA OpROM support, seems working on RX550, please check current main branch.

Binary csmwrap.efi link please. Tested this build: https://github.com/FlyGoat/csmwrap/actions/runs/15122472115 Memory Remap - Enabled iGPU - SeaVGABIOS PCIe AMD6450 - AMD VBIOS Windows 8 Developer Preview 32-bit: Image

mini XP 32-bit from HBCD14: Image

WinXP SP2 32-bit + Longhorn 5472 winload.exe loader stuck on aurora bootscreen but works (AMD6450 VBIOS) - Remote Desktop screenshot: Image

Same WinXP SP2 but loader ntldr+NTDETECT.COM > same error as miniXP HBCD14:

Windows NT has found only 0K of low memory. 512k of low memory
is required to run Windows NT. You may need to upgrade your
computer or run a configuration program provided by the manufacturer.

Gelip avatar May 20 '25 02:05 Gelip