From: Mark Kettenis Subject: Re: sys/amd64: fallback to VGA text mode on headless systems To: Kirill A. Korinsky Cc: tech@openbsd.org Date: Fri, 30 Jan 2026 23:05:37 +0100 > Date: Fri, 30 Jan 2026 20:39:34 +0100 > From: Kirill A. Korinsky > > On Tue, 27 Jan 2026 15:23:55 +0100, > Kirill A. Korinsky wrote: > > > > On Tue, 27 Jan 2026 13:18:50 +0100, > > Crystal Kolipe wrote: > > > > > > On Tue, Jan 27, 2026 at 11:31:50AM +0000, Stuart Henderson wrote: > > > > On 2026/01/27 12:05, Kirill A. Korinsky wrote: > > > > > On Tue, 27 Jan 2026 10:21:02 +0100, > > > > > Crystal Kolipe wrote: > > > > > > Whilst it fixes your machine, how confident can we be that this is harmless on > > > > > > others? > > > > > > > > > > > > It's perfectly valid to have no graphics hardware at all and run entirely from > > > > > > a serial console, so this could plausibly break machines that are currently > > > > > > working just fine. > > > > > > > > > > > > > > > > Well, here my assumption that on amd64, both the VGA legacy memory region > > > > > and I/O ports is still reserved and not used. > > > > > > > > if my reading is correct then I think that is ok in this case (but I'm > > > > not 100%) .. > > > > > > > > boot> machine mem > > > > Region 0: type 1 at 0x0 for 639KB > > > > Region 1: type 2 at 0x9fc00 for 1KB > > > > Region 2: type 2 at 0xf0000 for 64KB > > > > Region 3: type 1 at 0x100000 for 2078296KB > > > > Region 4: type 2 at 0x7ee96000 for 17832KB > > > > Region 5: type 2 at 0xf8000000 for 65536KB > > > > Region 6: type 2 at 0xfec10000 for 4KB > > > > Region 7: type 2 at 0xfed40000 for 20KB > > > > Low ram: 639KB High ram: 2078296KB > > > > Total free memory: 2078935KB > > > > > > The VGA memory space is certainly marked as reserved. > > > > > > But 'reserved' doesn't mean that writing arbitrary values to those addresses > > > is harmless. > > > > > > > But for compatiblity it should stay reserved for VGA, and to reuse it for > > something else BIOS should have two code paths: when VGA is avaialbel and > > when it isn't. > > > > This is quite small region and introduce two code path seems strange. > > > > But, again, here many assumptions. > > > > Here the second attempt. This time it is looks safer. > > Idea to scan PCI bus to find some VGA adapter and use it as primamary. > > More or less similar with Loongson's approach. > > It allows to boot this machine without serial and amdgpu and dmesg has: > > ~ $ grep vga /var/run/dmesg.boot > vga1 at pci13 dev 0 function 0 "ATI Raphael" rev 0xc9 > wsdisplay0 at vga1 mux 1: console (80x25, vt100 emulation) > ~ $ > > which is expected. > > Thoughts? Tests? OKs? What about my suggestion to have a dummy framebuffer? > Index: sys/arch/amd64/amd64/wscons_machdep.c > =================================================================== > RCS file: /home/cvs/src/sys/arch/amd64/amd64/wscons_machdep.c,v > diff -u -p -r1.14 wscons_machdep.c > --- sys/arch/amd64/amd64/wscons_machdep.c 14 Oct 2017 04:44:43 -0000 1.14 > +++ sys/arch/amd64/amd64/wscons_machdep.c 30 Jan 2026 19:28:07 -0000 > @@ -35,6 +35,10 @@ > #include > > #include "vga.h" > +#if NVGA_PCI > 0 > +#include > +#include > +#endif > #include "pcdisplay.h" > #if (NVGA > 0) || (NPCDISPLAY > 0) > #include > @@ -150,6 +154,11 @@ wscn_video_init(void) > #endif > #if (NPCDISPLAY > 0) > if (pcdisplay_cnattach(X86_BUS_SPACE_IO, X86_BUS_SPACE_MEM) == 0) > + return (0); > +#endif > +#if NVGA_PCI > 0 > + if (vga_pci_cnattach_scan(X86_BUS_SPACE_IO, X86_BUS_SPACE_MEM, > + NULL) == 0) > return (0); > #endif > return (-1); > Index: sys/dev/pci/vga_pci.c > =================================================================== > RCS file: /home/cvs/src/sys/dev/pci/vga_pci.c,v > diff -u -p -r1.92 vga_pci.c > --- sys/dev/pci/vga_pci.c 12 Jun 2025 09:17:46 -0000 1.92 > +++ sys/dev/pci/vga_pci.c 30 Jan 2026 19:28:00 -0000 > @@ -287,6 +287,39 @@ vga_pci_cnattach(bus_space_tag_t iot, bu > } > > int > +vga_pci_cnattach_scan(bus_space_tag_t iot, bus_space_tag_t memt, > + pci_chipset_tag_t pc) > +{ > + pcitag_t tag; > + pcireg_t id, class, cmd; > + int bus, dev; > + > + for (bus = 0; bus < 256; bus++) { > + for (dev = 0; dev < 32; dev++) { > + tag = pci_make_tag(pc, bus, dev, 0); > + id = pci_conf_read(pc, tag, PCI_ID_REG); > + if (id == 0 || PCI_VENDOR(id) == PCI_VENDOR_INVALID) > + continue; > + > + class = pci_conf_read(pc, tag, PCI_CLASS_REG); > + if (!DEVICE_IS_VGA_PCI(class)) > + continue; > + > + cmd = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); > + if ((cmd & (PCI_COMMAND_IO_ENABLE | > + PCI_COMMAND_MEM_ENABLE)) != > + (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE)) > + continue; > + > + if (vga_pci_cnattach(iot, memt, NULL, bus, dev, 0) == 0) > + return (0); > + } > + } > + > + return (ENXIO); > +} > + > +int > vga_pci_ioctl(void *v, u_long cmd, caddr_t addr, int flag, struct proc *pb) > { > int error = 0; > Index: sys/dev/pci/vga_pcivar.h > =================================================================== > RCS file: /home/cvs/src/sys/dev/pci/vga_pcivar.h,v > diff -u -p -r1.20 vga_pcivar.h > --- sys/dev/pci/vga_pcivar.h 29 Oct 2015 07:47:03 -0000 1.20 > +++ sys/dev/pci/vga_pcivar.h 30 Jan 2026 19:27:47 -0000 > @@ -82,6 +82,8 @@ struct vga_pci_softc { > #endif > }; > > +int vga_pci_cnattach_scan(bus_space_tag_t, bus_space_tag_t, > + pci_chipset_tag_t); > int vga_pci_cnattach(bus_space_tag_t, bus_space_tag_t, > pci_chipset_tag_t, int, int, int); > int vga_aperture_needed(struct pci_attach_args *); > >